aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/CHANGELOG2
-rw-r--r--actionpack/actionpack.gemspec7
-rw-r--r--actionpack/lib/abstract_controller/asset_paths.rb2
-rw-r--r--actionpack/lib/abstract_controller/layouts.rb3
-rw-r--r--actionpack/lib/action_controller/base.rb8
-rw-r--r--actionpack/lib/action_controller/metal/request_forgery_protection.rb2
-rw-r--r--actionpack/lib/action_dispatch/http/mime_negotiation.rb3
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb27
-rw-r--r--actionpack/lib/action_dispatch/routing/polymorphic_routes.rb9
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb6
-rw-r--r--actionpack/lib/action_view/helpers/date_helper.rb94
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb45
-rw-r--r--actionpack/lib/action_view/helpers/form_tag_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/number_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/translation_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/url_helper.rb8
-rw-r--r--actionpack/lib/action_view/renderer/partial_renderer.rb54
-rw-r--r--actionpack/lib/action_view/template/resolver.rb2
-rw-r--r--actionpack/lib/sprockets/assets.rake28
-rw-r--r--actionpack/lib/sprockets/helpers/rails_helper.rb2
-rw-r--r--actionpack/lib/sprockets/railtie.rb11
-rw-r--r--actionpack/test/controller/log_subscriber_test.rb19
-rw-r--r--actionpack/test/controller/render_test.rb14
-rw-r--r--actionpack/test/dispatch/mapper_test.rb7
-rw-r--r--actionpack/test/dispatch/prefix_generation_test.rb12
-rw-r--r--actionpack/test/dispatch/request_test.rb6
-rw-r--r--actionpack/test/dispatch/routing_test.rb20
-rw-r--r--actionpack/test/fixtures/test/_200.html.erb1
-rw-r--r--actionpack/test/template/asset_tag_helper_test.rb6
-rw-r--r--actionpack/test/template/render_test.rb9
-rw-r--r--actionpack/test/template/sprockets_helper_test.rb80
-rw-r--r--actionpack/test/template/test_test.rb2
-rw-r--r--actionpack/test/template/url_helper_test.rb8
34 files changed, 313 insertions, 192 deletions
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG
index 9d320ddb8d..9888be07a9 100644
--- a/actionpack/CHANGELOG
+++ b/actionpack/CHANGELOG
@@ -30,6 +30,8 @@
*Rails 3.1.0 (unreleased)*
+* The submit form helper does not generate an id "object_name_id" anymore. [fbrusatti]
+
* Make sure respond_with with :js tries to render a template in all cases [José Valim]
* json_escape will now return a SafeBuffer string if it receives SafeBuffer string [tenderlove]
diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec
index 88d892eb16..620fdc4a72 100644
--- a/actionpack/actionpack.gemspec
+++ b/actionpack/actionpack.gemspec
@@ -21,10 +21,11 @@ Gem::Specification.new do |s|
s.add_dependency('rack-cache', '~> 1.0.2')
s.add_dependency('builder', '~> 3.0.0')
s.add_dependency('i18n', '~> 0.6')
- s.add_dependency('rack', '~> 1.3.1')
+ s.add_dependency('rack', '~> 1.3.2')
s.add_dependency('rack-test', '~> 0.6.0')
s.add_dependency('rack-mount', '~> 0.8.1')
- s.add_dependency('sprockets', '= 2.0.0.beta.10')
- s.add_dependency('tzinfo', '~> 0.3.29')
+ s.add_dependency('sprockets', '~> 2.0.0.beta.12')
s.add_dependency('erubis', '~> 2.7.0')
+
+ s.add_development_dependency('tzinfo', '~> 0.3.29')
end
diff --git a/actionpack/lib/abstract_controller/asset_paths.rb b/actionpack/lib/abstract_controller/asset_paths.rb
index ad14cd6d87..b104d34fb5 100644
--- a/actionpack/lib/abstract_controller/asset_paths.rb
+++ b/actionpack/lib/abstract_controller/asset_paths.rb
@@ -3,7 +3,7 @@ module AbstractController
extend ActiveSupport::Concern
included do
- config_accessor :asset_host, :asset_path, :assets_dir, :javascripts_dir, :stylesheets_dir, :use_sprockets
+ config_accessor :asset_host, :asset_path, :assets_dir, :javascripts_dir, :stylesheets_dir
end
end
end
diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb
index d6f75bded0..10aa34c76b 100644
--- a/actionpack/lib/abstract_controller/layouts.rb
+++ b/actionpack/lib/abstract_controller/layouts.rb
@@ -139,7 +139,7 @@ module AbstractController
#
# end
#
- # This will assign "weblog_standard" as the WeblogController's layout for all actions except for the +rss+ action, which will
+ # This will assign "weblog_standard" as the WeblogController's layout for all actions except for the +rss+ action, which will
# be rendered directly, without wrapping a layout around the rendered view.
#
# Both the <tt>:only</tt> and <tt>:except</tt> condition can accept an arbitrary number of method references, so
@@ -167,6 +167,7 @@ module AbstractController
included do
class_attribute :_layout_conditions
+ remove_possible_method :_layout_conditions
delegate :_layout_conditions, :to => :'self.class'
self._layout_conditions = {}
_write_layout_method
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index d14c5f940b..ce56d8bc71 100644
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -212,16 +212,16 @@ module ActionController
# also include them at the bottom.
AbstractController::Callbacks,
+ # Append rescue at the bottom to wrap as much as possible.
+ Rescue,
+
# Add instrumentations hooks at the bottom, to ensure they instrument
# all the methods properly.
Instrumentation,
# Params wrapper should come before instrumentation so they are
# properly showed in logs
- ParamsWrapper,
-
- # The same with rescue, append it at the end to wrap as much as possible.
- Rescue
+ ParamsWrapper
]
MODULES.each do |mod|
diff --git a/actionpack/lib/action_controller/metal/request_forgery_protection.rb b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
index 258a40aea6..4d016271ea 100644
--- a/actionpack/lib/action_controller/metal/request_forgery_protection.rb
+++ b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
@@ -79,7 +79,7 @@ module ActionController #:nodoc:
end
end
- # This is the method that defines the application behaviour when a request is found to be unverified.
+ # This is the method that defines the application behavior when a request is found to be unverified.
# By default, \Rails resets the session when it finds an unverified request.
def handle_unverified_request
reset_session
diff --git a/actionpack/lib/action_dispatch/http/mime_negotiation.rb b/actionpack/lib/action_dispatch/http/mime_negotiation.rb
index 980c658ab7..5c48a60469 100644
--- a/actionpack/lib/action_dispatch/http/mime_negotiation.rb
+++ b/actionpack/lib/action_dispatch/http/mime_negotiation.rb
@@ -98,7 +98,8 @@ module ActionDispatch
BROWSER_LIKE_ACCEPTS = /,\s*\*\/\*|\*\/\*\s*,/
def valid_accept_header
- xhr? || (accept && accept !~ BROWSER_LIKE_ACCEPTS)
+ (xhr? && (accept || content_mime_type)) ||
+ (accept && accept !~ BROWSER_LIKE_ACCEPTS)
end
def use_accept_header
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index 65895590bf..003bc1dc2c 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -119,6 +119,8 @@ module ActionDispatch
path
elsif path.include?(":format") || path.end_with?('/')
path
+ elsif @options[:format] == true
+ "#{path}.:format"
else
"#{path}(.:format)"
end
@@ -190,13 +192,12 @@ module ActionDispatch
end
def blocks
- block = @scope[:blocks] || []
-
- if @options[:constraints].present? && !@options[:constraints].is_a?(Hash)
- block << @options[:constraints]
+ constraints = @options[:constraints]
+ if constraints.present? && !constraints.is_a?(Hash)
+ [constraints]
+ else
+ @scope[:blocks] || []
end
-
- block
end
def constraints
@@ -659,13 +660,13 @@ module ActionDispatch
#
# This generates the following routes:
#
- # admin_posts GET /admin/posts(.:format) {:action=>"index", :controller=>"admin/posts"}
- # admin_posts POST /admin/posts(.:format) {:action=>"create", :controller=>"admin/posts"}
- # new_admin_post GET /admin/posts/new(.:format) {:action=>"new", :controller=>"admin/posts"}
- # edit_admin_post GET /admin/posts/:id/edit(.:format) {:action=>"edit", :controller=>"admin/posts"}
- # admin_post GET /admin/posts/:id(.:format) {:action=>"show", :controller=>"admin/posts"}
- # admin_post PUT /admin/posts/:id(.:format) {:action=>"update", :controller=>"admin/posts"}
- # admin_post DELETE /admin/posts/:id(.:format) {:action=>"destroy", :controller=>"admin/posts"}
+ # admin_posts GET /admin/posts(.:format) admin/posts#index
+ # admin_posts POST /admin/posts(.:format) admin/posts#create
+ # new_admin_post GET /admin/posts/new(.:format) admin/posts#new
+ # edit_admin_post GET /admin/posts/:id/edit(.:format) admin/posts#edit
+ # admin_post GET /admin/posts/:id(.:format) admin/posts#show
+ # admin_post PUT /admin/posts/:id(.:format) admin/posts#update
+ # admin_post DELETE /admin/posts/:id(.:format) admin/posts#destroy
#
# === Options
#
diff --git a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb
index 49aef0bf72..e989a38d8b 100644
--- a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb
+++ b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb
@@ -124,14 +124,7 @@ module ActionDispatch
args.last.kind_of?(Hash) ? args.last.merge!(url_options) : args << url_options
end
- if proxy
- proxy.send(named_route, *args)
- else
- # we need to use url_for, because polymorphic_url can be used in context of other than
- # current routes (e.g. engine's routes). As named routes from engine are not included
- # calling engine's named route directly would fail.
- url_for _routes.url_helpers.__send__("hash_for_#{named_route}", *args)
- end
+ (proxy || self).send(named_route, *args)
end
# Returns the path component of a URL for the given record. It uses
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
index 509c29844a..7d01e5ddb8 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -154,7 +154,7 @@ module ActionView
# "/release-#{RELEASE_NUMBER}#{asset_path}"
# }
#
- # This example would cause the following behaviour on all servers no
+ # This example would cause the following behavior on all servers no
# matter when they were deployed:
#
# image_tag("rails.png")
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb
index 0f8a63901e..25cc561608 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb
@@ -83,11 +83,7 @@ module ActionView
# javascript_path "http://www.example.com/js/xmlhr" # => http://www.example.com/js/xmlhr
# javascript_path "http://www.example.com/js/xmlhr.js" # => http://www.example.com/js/xmlhr.js
def javascript_path(source)
- if config.use_sprockets
- asset_path(source, 'js')
- else
- asset_paths.compute_public_path(source, 'javascripts', 'js')
- end
+ asset_paths.compute_public_path(source, 'javascripts', 'js')
end
alias_method :path_to_javascript, :javascript_path # aliased to avoid conflicts with a javascript_path named route
diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb
index 6a724749f4..e850c258ce 100644
--- a/actionpack/lib/action_view/helpers/date_helper.rb
+++ b/actionpack/lib/action_view/helpers/date_helper.rb
@@ -8,8 +8,8 @@ module ActionView
module Helpers
# = Action View Date Helpers
#
- # The Date Helper primarily creates select/option tags for different kinds of dates and date elements. All of the
- # select-type methods share a number of common options that are as follows:
+ # The Date Helper primarily creates select/option tags for different kinds of dates and times or date and time
+ # elements. All of the select-type methods share a number of common options that are as follows:
#
# * <tt>:prefix</tt> - overwrites the default prefix of "date" used for the select names. So specifying "birthday"
# would give birthday[month] instead of date[month] if passed to the <tt>select_month</tt> method.
@@ -18,7 +18,7 @@ module ActionView
# the <tt>select_month</tt> method would use simply "date" (which can be overwritten using <tt>:prefix</tt>) instead
# of "date[month]".
module DateHelper
- # Reports the approximate distance in time between two Time or Date objects or integers as seconds.
+ # Reports the approximate distance in time between two Time, Date or DateTime objects or integers as seconds.
# Set <tt>include_seconds</tt> to true if you want more detailed approximations when distance < 1 min, 29 secs.
# Distances are reported based on the following table:
#
@@ -176,37 +176,37 @@ module ActionView
# NOTE: Discarded selects will default to 1. So if no month select is available, January will be assumed.
#
# ==== Examples
- # # Generates a date select that when POSTed is stored in the post variable, in the written_on attribute.
- # date_select("post", "written_on")
+ # # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute.
+ # date_select("article", "written_on")
#
- # # Generates a date select that when POSTed is stored in the post variable, in the written_on attribute,
+ # # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute,
# # with the year in the year drop down box starting at 1995.
- # date_select("post", "written_on", :start_year => 1995)
+ # date_select("article", "written_on", :start_year => 1995)
#
- # # Generates a date select that when POSTed is stored in the post variable, in the written_on attribute,
+ # # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute,
# # with the year in the year drop down box starting at 1995, numbers used for months instead of words,
# # and without a day select box.
- # date_select("post", "written_on", :start_year => 1995, :use_month_numbers => true,
+ # date_select("article", "written_on", :start_year => 1995, :use_month_numbers => true,
# :discard_day => true, :include_blank => true)
#
- # # Generates a date select that when POSTed is stored in the post variable, in the written_on attribute
+ # # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute
# # with the fields ordered as day, month, year rather than month, day, year.
- # date_select("post", "written_on", :order => [:day, :month, :year])
+ # date_select("article", "written_on", :order => [:day, :month, :year])
#
# # Generates a date select that when POSTed is stored in the user variable, in the birthday attribute
# # lacking a year field.
# date_select("user", "birthday", :order => [:month, :day])
#
- # # Generates a date select that when POSTed is stored in the post variable, in the written_on attribute
+ # # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute
# # which is initially set to the date 3 days from the current date
- # date_select("post", "written_on", :default => 3.days.from_now)
+ # date_select("article", "written_on", :default => 3.days.from_now)
#
# # Generates a date select that when POSTed is stored in the credit_card variable, in the bill_due attribute
# # that will have a default day of 20.
# date_select("credit_card", "bill_due", :default => { :day => 20 })
#
# # Generates a date select with custom prompts.
- # date_select("post", "written_on", :prompt => { :day => 'Select day', :month => 'Select month', :year => 'Select year' })
+ # date_select("article", "written_on", :prompt => { :day => 'Select day', :month => 'Select month', :year => 'Select year' })
#
# The selects are prepared for multi-parameter assignment to an Active Record object.
#
@@ -228,20 +228,20 @@ module ActionView
# If anything is passed in the html_options hash it will be applied to every select tag in the set.
#
# ==== Examples
- # # Creates a time select tag that, when POSTed, will be stored in the post variable in the sunrise attribute.
- # time_select("post", "sunrise")
+ # # Creates a time select tag that, when POSTed, will be stored in the article variable in the sunrise attribute.
+ # time_select("article", "sunrise")
#
- # # Creates a time select tag with a seconds field that, when POSTed, will be stored in the post variables in
+ # # Creates a time select tag with a seconds field that, when POSTed, will be stored in the article variables in
# # the sunrise attribute.
- # time_select("post", "start_time", :include_seconds => true)
+ # time_select("article", "start_time", :include_seconds => true)
#
# # You can set the <tt>:minute_step</tt> to 15 which will give you: 00, 15, 30 and 45.
# time_select 'game', 'game_time', {:minute_step => 15}
#
# # Creates a time select tag with a custom prompt. Use <tt>:prompt => true</tt> for generic prompts.
- # time_select("post", "written_on", :prompt => {:hour => 'Choose hour', :minute => 'Choose minute', :second => 'Choose seconds'})
- # time_select("post", "written_on", :prompt => {:hour => true}) # generic prompt for hours
- # time_select("post", "written_on", :prompt => true) # generic prompts for all
+ # time_select("article", "written_on", :prompt => {:hour => 'Choose hour', :minute => 'Choose minute', :second => 'Choose seconds'})
+ # time_select("article", "written_on", :prompt => {:hour => true}) # generic prompt for hours
+ # time_select("article", "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}
@@ -261,36 +261,36 @@ module ActionView
# If anything is passed in the html_options hash it will be applied to every select tag in the set.
#
# ==== Examples
- # # Generates a datetime select that, when POSTed, will be stored in the post variable in the written_on
+ # # Generates a datetime select that, when POSTed, will be stored in the article variable in the written_on
# # attribute.
- # datetime_select("post", "written_on")
+ # datetime_select("article", "written_on")
#
# # Generates a datetime select with a year select that starts at 1995 that, when POSTed, will be stored in the
- # # post variable in the written_on attribute.
- # datetime_select("post", "written_on", :start_year => 1995)
+ # # article variable in the written_on attribute.
+ # datetime_select("article", "written_on", :start_year => 1995)
#
# # Generates a datetime select with a default value of 3 days from the current time that, when POSTed, will
# # 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)
+ # datetime_select("article", "written_on", :ampm => true)
#
- # # Generates a datetime select that discards the type that, when POSTed, will be stored in the post variable
+ # # Generates a datetime select that discards the type that, when POSTed, will be stored in the article variable
# # as the written_on attribute.
- # datetime_select("post", "written_on", :discard_type => true)
+ # datetime_select("article", "written_on", :discard_type => true)
#
# # Generates a datetime select with a custom prompt. Use <tt>:prompt => true</tt> for generic prompts.
- # datetime_select("post", "written_on", :prompt => {:day => 'Choose day', :month => 'Choose month', :year => 'Choose year'})
- # datetime_select("post", "written_on", :prompt => {:hour => true}) # generic prompt for hours
- # datetime_select("post", "written_on", :prompt => true) # generic prompts for all
+ # datetime_select("article", "written_on", :prompt => {:day => 'Choose day', :month => 'Choose month', :year => 'Choose year'})
+ # datetime_select("article", "written_on", :prompt => {:hour => true}) # generic prompt for hours
+ # datetime_select("article", "written_on", :prompt => true) # generic prompts for all
#
# The selects are prepared for multi-parameter assignment to an Active Record object.
def datetime_select(object_name, method, options = {}, html_options = {})
InstanceTag.new(object_name, method, self, options.delete(:object)).to_datetime_select_tag(options, html_options)
end
- # Returns a set of html select-tags (one for year, month, day, hour, and minute) pre-selected with the
+ # Returns a set of html select-tags (one for year, month, day, hour, minute, and second) pre-selected with the
# +datetime+. It's also possible to explicitly set the order of the tags using the <tt>:order</tt> option with
# an array of symbols <tt>:year</tt>, <tt>:month</tt> and <tt>:day</tt> in the desired order. If you do not
# supply a Symbol, it will be appended onto the <tt>:order</tt> passed in. You can also add
@@ -343,15 +343,15 @@ module ActionView
# Returns a set of html select-tags (one for year, month, and day) pre-selected with the +date+.
# It's possible to explicitly set the order of the tags using the <tt>:order</tt> option with an array of
- # symbols <tt>:year</tt>, <tt>:month</tt> and <tt>:day</tt> in the desired order. If you do not supply a Symbol,
- # it will be appended onto the <tt>:order</tt> passed in.
+ # symbols <tt>:year</tt>, <tt>:month</tt> and <tt>:day</tt> in the desired order.
+ # If the array passed to the <tt>:order</tt> option does not contain all the three symbols, all tags will be hidden.
#
# If anything is passed in the html_options hash it will be applied to every select tag in the set.
#
# ==== Examples
- # my_date = Time.today + 6.days
+ # my_date = Time.now + 6.days
#
- # # Generates a date select that defaults to the date in my_date (six days afteri today).
+ # # Generates a date select that defaults to the date in my_date (six days after today).
# select_date(my_date)
#
# # Generates a date select that defaults to today (no specified date).
@@ -422,7 +422,7 @@ module ActionView
end
# Returns a select tag with options for each of the seconds 0 through 59 with the current second selected.
- # The <tt>second</tt> can also be substituted for a second number.
+ # The <tt>datetime</tt> can be either a +Time+ or +DateTime+ object or an integer.
# Override the field name using the <tt>:field_name</tt> option, 'second' by default.
#
# ==== Examples
@@ -440,7 +440,7 @@ module ActionView
#
# # Generates a select field for seconds with a custom prompt. Use <tt>:prompt => true</tt> for a
# # generic prompt.
- # select_minute(14, :prompt => 'Choose seconds')
+ # select_second(14, :prompt => 'Choose seconds')
#
def select_second(datetime, options = {}, html_options = {})
DateTimeSelector.new(datetime, options, html_options).select_second
@@ -448,21 +448,21 @@ module ActionView
# Returns a select tag with options for each of the minutes 0 through 59 with the current minute selected.
# Also can return a select tag with options by <tt>minute_step</tt> from 0 through 59 with the 00 minute
- # selected. The <tt>minute</tt> can also be substituted for a minute number.
+ # selected. The <tt>datetime</tt> can be either a +Time+ or +DateTime+ object or an integer.
# Override the field name using the <tt>:field_name</tt> option, 'minute' by default.
#
# ==== Examples
# my_time = Time.now + 6.hours
#
- # # Generates a select field for minutes that defaults to the minutes for the time in my_tiime.
+ # # Generates a select field for minutes that defaults to the minutes for the time in my_time.
# select_minute(my_time)
#
# # Generates a select field for minutes that defaults to the number given.
# select_minute(14)
#
# # Generates a select field for minutes that defaults to the minutes for the time in my_time
- # # that is named 'stride' rather than 'second'.
- # select_minute(my_time, :field_name => 'stride')
+ # # that is named 'moment' rather than 'minute'.
+ # select_minute(my_time, :field_name => 'moment')
#
# # Generates a select field for minutes with a custom prompt. Use <tt>:prompt => true</tt> for a
# # generic prompt.
@@ -473,7 +473,7 @@ module ActionView
end
# Returns a select tag with options for each of the hours 0 through 23 with the current hour selected.
- # The <tt>hour</tt> can also be substituted for a hour number.
+ # The <tt>datetime</tt> can be either a +Time+ or +DateTime+ object or an integer.
# Override the field name using the <tt>:field_name</tt> option, 'hour' by default.
#
# ==== Examples
@@ -485,8 +485,8 @@ module ActionView
# # Generates a select field for hours that defaults to the number given.
# select_hour(13)
#
- # # Generates a select field for hours that defaults to the minutes for the time in my_time
- # # that is named 'stride' rather than 'second'.
+ # # Generates a select field for hours that defaults to the hour for the time in my_time
+ # # that is named 'stride' rather than 'hour'.
# select_hour(my_time, :field_name => 'stride')
#
# # Generates a select field for hours with a custom prompt. Use <tt>:prompt => true</tt> for a
@@ -501,11 +501,11 @@ module ActionView
end
# Returns a select tag with options for each of the days 1 through 31 with the current day selected.
- # The <tt>date</tt> can also be substituted for a hour number.
+ # The <tt>date</tt> can also be substituted for a day number.
# Override the field name using the <tt>:field_name</tt> option, 'day' by default.
#
# ==== Examples
- # my_date = Time.today + 2.days
+ # my_date = Time.now + 2.days
#
# # Generates a select field for days that defaults to the day for the date in my_date.
# select_day(my_time)
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index 89bd1365cd..52a640abf3 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -49,7 +49,7 @@ module ActionView
# <label for="person_last_name">Last name</label>:
# <input id="person_last_name" name="person[last_name]" size="30" type="text" /><br />
#
- # <input id="person_submit" name="commit" type="submit" value="Create Person" />
+ # <input name="commit" type="submit" value="Create Person" />
# </form>
#
# As you see, the HTML reflects knowledge about the resource in several spots,
@@ -80,7 +80,7 @@ module ActionView
# <label for="person_last_name">Last name</label>:
# <input id="person_last_name" name="person[last_name]" size="30" type="text" value="Smith" /><br />
#
- # <input id="person_submit" name="commit" type="submit" value="Update Person" />
+ # <input name="commit" type="submit" value="Update Person" />
# </form>
#
# Note that the endpoint, default values, and submit button label are tailored for <tt>@person</tt>.
@@ -233,7 +233,7 @@ module ActionView
# <% end %>
#
# If your resource has associations defined, for example, you want to add comments
- # to the post given that the routes are set correctly:
+ # to the document given that the routes are set correctly:
#
# <%= form_for([@document, @comment]) do |f| %>
# ...
@@ -259,8 +259,8 @@ module ActionView
# :remote => true
#
# in the options hash creates a form that will allow the unobtrusive JavaScript drivers to modify its
- # behaviour. The expected default behaviour is an XMLHttpRequest in the background instead of the regular
- # POST arrangement, but ultimately the behaviour is the choice of the JavaScript driver implementor.
+ # behavior. The expected default behavior is an XMLHttpRequest in the background instead of the regular
+ # POST arrangement, but ultimately the behavior is the choice of the JavaScript driver implementor.
# Even though it's using JavaScript to serialize the form elements, the form submission will work just like
# a regular submission as viewed by the receiving side (all elements available in <tt>params</tt>).
#
@@ -859,7 +859,28 @@ module ActionView
InstanceTag.new(object_name, method, self, options.delete(:object)).to_radio_button_tag(tag_value, options)
end
- # Returns a text_field of type "search".
+ # Returns an input of type "search" for accessing a specified attribute (identified by +method+) on an object
+ # assigned to the template (identified by +object_name+). Inputs of type "search" may be styled differently by
+ # some browsers.
+ #
+ # ==== Examples
+ #
+ # search_field(:user, :name)
+ # # => <input id="user_name" name="user[name]" size="30" type="search" />
+ # search_field(:user, :name, :autosave => false)
+ # # => <input autosave="false" id="user_name" name="user[name]" size="30" type="search" />
+ # search_field(:user, :name, :results => 3)
+ # # => <input id="user_name" name="user[name]" results="3" size="30" type="search" />
+ # # Assume request.host returns "www.example.com"
+ # search_field(:user, :name, :autosave => true)
+ # # => <input autosave="com.example.www" id="user_name" name="user[name]" results="10" size="30" type="search" />
+ # search_field(:user, :name, :onsearch => true)
+ # # => <input id="user_name" incremental="true" name="user[name]" onsearch="true" size="30" type="search" />
+ # search_field(:user, :name, :autosave => false, :onsearch => true)
+ # # => <input autosave="false" id="user_name" incremental="true" name="user[name]" onsearch="true" size="30" type="search" />
+ # search_field(:user, :name, :autosave => true, :onsearch => true)
+ # # => <input autosave="com.example.www" id="user_name" incremental="true" name="user[name]" onsearch="true" results="10" size="30" type="search" />
+ #
def search_field(object_name, method, options = {})
options = options.stringify_keys
@@ -878,17 +899,29 @@ module ActionView
end
# Returns a text_field of type "tel".
+ #
+ # telephone_field("user", "phone")
+ # # => <input id="user_phone" name="user[phone]" size="30" type="tel" />
+ #
def telephone_field(object_name, method, options = {})
InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("tel", options)
end
alias phone_field telephone_field
# Returns a text_field of type "url".
+ #
+ # url_field("user", "homepage")
+ # # => <input id="user_homepage" size="30" name="user[homepage]" type="url" />
+ #
def url_field(object_name, method, options = {})
InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("url", options)
end
# Returns a text_field of type "email".
+ #
+ # email_field("user", "address")
+ # # => <input id="user_address" size="30" name="user[address]" type="email" />
+ #
def email_field(object_name, method, options = {})
InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("email", options)
end
diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb
index 72bc4510b5..822686b09d 100644
--- a/actionpack/lib/action_view/helpers/form_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb
@@ -30,7 +30,7 @@ module ActionView
# (by passing <tt>false</tt>).
# * A list of parameters to feed to the URL the form will be posted to.
# * <tt>:remote</tt> - If set to true, will allow the Unobtrusive JavaScript drivers to control the
- # submit behaviour. By default this behaviour is an ajax submit.
+ # submit behavior. By default this behavior is an ajax submit.
#
# ==== Examples
# form_tag('/posts')
diff --git a/actionpack/lib/action_view/helpers/number_helper.rb b/actionpack/lib/action_view/helpers/number_helper.rb
index fe0288521f..ec6c2c8db3 100644
--- a/actionpack/lib/action_view/helpers/number_helper.rb
+++ b/actionpack/lib/action_view/helpers/number_helper.rb
@@ -1,3 +1,5 @@
+# encoding: utf-8
+
require 'active_support/core_ext/big_decimal/conversions'
require 'active_support/core_ext/float/rounding'
require 'active_support/core_ext/object/blank'
diff --git a/actionpack/lib/action_view/helpers/translation_helper.rb b/actionpack/lib/action_view/helpers/translation_helper.rb
index 26b6e8b599..be64dc823e 100644
--- a/actionpack/lib/action_view/helpers/translation_helper.rb
+++ b/actionpack/lib/action_view/helpers/translation_helper.rb
@@ -25,7 +25,7 @@ module ActionView
# * a titleized version of the last key segment as a text.
#
# E.g. the value returned for a missing translation key :"blog.post.title" will be
- # <span class="translation_missing" title="translation missing: blog.post.title">Title</span>.
+ # <span class="translation_missing" title="translation missing: en.blog.post.title">Title</span>.
# This way your views will display rather reasonable strings but it will still
# be easy to spot missing translations.
#
diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb
index d70ae4196b..51baca8e03 100644
--- a/actionpack/lib/action_view/helpers/url_helper.rb
+++ b/actionpack/lib/action_view/helpers/url_helper.rb
@@ -55,8 +55,8 @@ module ActionView
#
# ==== Relying on named routes
#
- # Passing a record (like an Active Record or Active Resource) 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
+ # Passing a record (like an Active Record or Active Resource) 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).
#
@@ -113,7 +113,7 @@ module ActionView
end
# 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
+ # 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
# value of the String as the href for the link. Using a <tt>:back</tt> Symbol instead
# of an options hash will generate a link to the referrer (a JavaScript back link
@@ -278,7 +278,7 @@ module ActionView
# prompt with the question specified. If the user accepts, the link is
# processed normally, otherwise no action is taken.
# * <tt>:remote</tt> - If set to true, will allow the Unobtrusive JavaScript drivers to control the
- # submit behaviour. By default this behaviour is an ajax submit.
+ # submit behavior. By default this behavior is an ajax submit.
# * <tt>:form_class</tt> - This controls the class of the form within which the submit button will
# be placed
#
diff --git a/actionpack/lib/action_view/renderer/partial_renderer.rb b/actionpack/lib/action_view/renderer/partial_renderer.rb
index a351fbc04f..c0ac332c4e 100644
--- a/actionpack/lib/action_view/renderer/partial_renderer.rb
+++ b/actionpack/lib/action_view/renderer/partial_renderer.rb
@@ -12,8 +12,7 @@ module ActionView
#
# <%= render :partial => "account" %>
#
- # This would render "advertiser/_account.html.erb" and pass the instance variable @account in as a local variable
- # +account+ to the template for display.
+ # This would render "advertiser/_account.html.erb".
#
# In another template for Advertiser#buy, we could have:
#
@@ -28,32 +27,24 @@ module ActionView
#
# == The :as and :object options
#
- # By default <tt>ActionView::Partials::PartialRenderer</tt> has its object in a local variable with the same
- # name as the template. So, given
+ # By default <tt>ActionView::Partials::PartialRenderer</tt> doesn't have any local variables.
+ # The <tt>:object</tt> option can be used to pass an object to the partial. For instance:
#
- # <%= render :partial => "contract" %>
+ # <%= render :partial => "account", :object => @buyer %>
#
- # within contract we'll get <tt>@contract</tt> in the local variable +contract+, as if we had written
+ # would provide the +@buyer+ object to the partial, available under the local variable +account+ and is
+ # equivalent to:
#
- # <%= render :partial => "contract", :locals => { :contract => @contract } %>
+ # <%= render :partial => "account", :locals => { :account => @buyer } %>
#
# With the <tt>:as</tt> option we can specify a different name for said local variable. For example, if we
- # wanted it to be +agreement+ instead of +contract+ we'd do:
- #
- # <%= render :partial => "contract", :as => 'agreement' %>
- #
- # The <tt>:object</tt> option can be used to directly specify which object is rendered into the partial;
- # useful when the template's object is elsewhere, in a different ivar or in a local variable for instance.
+ # wanted it to be +user+ instead of +account+ we'd do:
#
- # Revisiting a previous example we could have written this code:
+ # <%= render :partial => "account", :object => @buyer, :as => 'user' %>
#
- # <%= render :partial => "account", :object => @buyer %>
- #
- # <% @advertisements.each do |ad| %>
- # <%= render :partial => "ad", :object => ad %>
- # <% end %>
+ # This is equivalent to
#
- # The <tt>:object</tt> and <tt>:as</tt> options can be used together.
+ # <%= render :partial => "account", :locals => { :user => @buyer } %>
#
# == Rendering a collection of partials
#
@@ -300,6 +291,11 @@ module ActionView
else
paths.map! { |path| retrieve_variable(path).unshift(path) }
end
+ if String === partial && @variable.to_s !~ /^[a-z_][a-zA-Z_0-9]*$/
+ raise ArgumentError.new("The partial name (#{partial}) is not a valid Ruby identifier; " +
+ "make sure your partial name starts with a letter or underscore, " +
+ "and is followed by any combinations of letters, numbers, or underscores.")
+ end
self
end
@@ -366,11 +362,25 @@ module ActionView
def partial_path(object = @object)
@partial_names[object.class.name] ||= begin
object = object.to_model if object.respond_to?(:to_model)
-
object.class.model_name.partial_path.dup.tap do |partial|
path = @lookup_context.prefixes.first
- partial.insert(0, "#{File.dirname(path)}/") if partial.include?(?/) && path.include?(?/)
+ merge_path_into_partial(path, partial)
+ end
+ end
+ end
+
+ def merge_path_into_partial(path, partial)
+ if path.include?(?/) && partial.include?(?/)
+ overlap = []
+ path_array = File.dirname(path).split('/')
+ partial_array = partial.split('/')[0..-3] # skip model dir & partial
+
+ path_array.each_with_index do |dir, index|
+ overlap << dir if dir == partial_array[index]
end
+
+ partial.gsub!(/^#{overlap.join('/')}\//,'')
+ partial.insert(0, "#{File.dirname(path)}/")
end
end
diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb
index 2b9427ace5..5f7fe81bd5 100644
--- a/actionpack/lib/action_view/template/resolver.rb
+++ b/actionpack/lib/action_view/template/resolver.rb
@@ -161,7 +161,7 @@ module ActionView
# Returns the file mtime from the filesystem.
def mtime(p)
- File.stat(p).mtime
+ File.mtime(p)
end
# Extract handler and formats from path. If a format cannot be a found neither
diff --git a/actionpack/lib/sprockets/assets.rake b/actionpack/lib/sprockets/assets.rake
index 0236350576..50278cffcd 100644
--- a/actionpack/lib/sprockets/assets.rake
+++ b/actionpack/lib/sprockets/assets.rake
@@ -1,26 +1,24 @@
namespace :assets do
+ # Ensures the RAILS_GROUPS environment variable is set
+ task :ensure_env do
+ ENV["RAILS_GROUPS"] ||= "assets"
+ end
+
desc "Compile all the assets named in config.assets.precompile"
- task :precompile do
- if ENV["RAILS_GROUPS"].to_s.empty?
- ENV["RAILS_GROUPS"] = "assets"
- Kernel.exec $0, *ARGV
- else
- Rake::Task["environment"].invoke
- Sprockets::Helpers::RailsHelper
+ task :precompile => :ensure_env do
+ Rake::Task["environment"].invoke
+ Sprockets::Helpers::RailsHelper
- assets = Rails.application.config.assets.precompile
- Rails.application.assets.precompile(*assets)
- end
+ assets = Rails.application.config.assets.precompile
+ # Always perform caching so that asset_path appends the timestamps to file references.
+ Rails.application.config.action_controller.perform_caching = true
+ Rails.application.assets.precompile(*assets)
end
desc "Remove compiled assets"
task :clean => :environment do
assets = Rails.application.config.assets
public_asset_path = Rails.public_path + assets.prefix
- file_list = FileList.new("#{public_asset_path}/**/*")
- file_list.each do |file|
- rm_rf file
- rm_rf "#{file}.gz"
- end
+ rm_rf public_asset_path, :secure => true
end
end
diff --git a/actionpack/lib/sprockets/helpers/rails_helper.rb b/actionpack/lib/sprockets/helpers/rails_helper.rb
index a95e7c0649..ec3d36d5ad 100644
--- a/actionpack/lib/sprockets/helpers/rails_helper.rb
+++ b/actionpack/lib/sprockets/helpers/rails_helper.rb
@@ -72,6 +72,8 @@ module Sprockets
def debug_assets?
params[:debug_assets] == '1' ||
params[:debug_assets] == 'true'
+ rescue NoMethodError
+ false
end
# Override to specify an alternative prefix for asset path generation.
diff --git a/actionpack/lib/sprockets/railtie.rb b/actionpack/lib/sprockets/railtie.rb
index 4906ad9a9c..83799d2b4d 100644
--- a/actionpack/lib/sprockets/railtie.rb
+++ b/actionpack/lib/sprockets/railtie.rb
@@ -11,13 +11,6 @@ module Sprockets
load "sprockets/assets.rake"
end
- # Configure ActionController to use sprockets.
- initializer "sprockets.set_configs", :after => "action_controller.set_configs" do |app|
- ActiveSupport.on_load(:action_controller) do
- self.use_sprockets = app.config.assets.enabled
- end
- end
-
# We need to configure this after initialization to ensure we collect
# paths from all engines. This hook is invoked exactly before routes
# are compiled, and so that other Railties have an opportunity to
@@ -61,10 +54,10 @@ module Sprockets
env.paths.concat assets.paths
end
- env.logger = Rails.logger
+ env.logger = ::Rails.logger
if env.respond_to?(:cache) && assets.cache_store != false
- env.cache = ActiveSupport::Cache.lookup_store(assets.cache_store) || Rails.cache
+ env.cache = ActiveSupport::Cache.lookup_store(assets.cache_store) || ::Rails.cache
end
if assets.compress
diff --git a/actionpack/test/controller/log_subscriber_test.rb b/actionpack/test/controller/log_subscriber_test.rb
index 80c4fa2ee5..ccdfcb0b2c 100644
--- a/actionpack/test/controller/log_subscriber_test.rb
+++ b/actionpack/test/controller/log_subscriber_test.rb
@@ -6,6 +6,13 @@ module Another
class LogSubscribersController < ActionController::Base
wrap_parameters :person, :include => :name, :format => :json
+ class SpecialException < Exception
+ end
+
+ rescue_from SpecialException do
+ head :status => 406
+ end
+
def show
render :nothing => true
end
@@ -39,6 +46,10 @@ module Another
raise Exception
end
+ def with_rescued_exception
+ raise SpecialException
+ end
+
end
end
@@ -195,6 +206,14 @@ class ACLogSubscriberTest < ActionController::TestCase
assert_match(/Completed 500/, logs.last)
end
+ def test_process_action_with_rescued_exception_includes_http_status_code
+ get :with_rescued_exception
+ wait
+
+ assert_equal 2, logs.size
+ assert_match(/Completed 406/, logs.last)
+ end
+
def logs
@logs ||= @logger.logged(:info)
end
diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb
index be59da9105..ce4b407c7d 100644
--- a/actionpack/test/controller/render_test.rb
+++ b/actionpack/test/controller/render_test.rb
@@ -14,6 +14,14 @@ module Fun
end
end
+module Quiz
+ class QuestionsController < ActionController::Base
+ def new
+ render :partial => Quiz::Question.new("Namespaced Partial")
+ end
+ end
+end
+
class TestController < ActionController::Base
protect_from_forgery
@@ -1251,6 +1259,12 @@ class RenderTest < ActionController::TestCase
assert_template('fun/games/_form')
end
+ def test_namespaced_object_partial
+ @controller = Quiz::QuestionsController.new
+ get :new
+ assert_equal "Namespaced Partial", @response.body
+ end
+
def test_partial_collection
get :partial_collection
assert_equal "Hello: davidHello: mary", @response.body
diff --git a/actionpack/test/dispatch/mapper_test.rb b/actionpack/test/dispatch/mapper_test.rb
index b6c08ffc33..81f0efb76e 100644
--- a/actionpack/test/dispatch/mapper_test.rb
+++ b/actionpack/test/dispatch/mapper_test.rb
@@ -83,6 +83,13 @@ module ActionDispatch
assert_equal '/*path', fakeset.conditions.first[:path_info]
assert_nil fakeset.requirements.first[:path]
end
+
+ def test_map_wildcard_with_format_true
+ fakeset = FakeSet.new
+ mapper = Mapper.new fakeset
+ mapper.match '/*path', :to => 'pages#show', :format => true
+ assert_equal '/*path.:format', fakeset.conditions.first[:path_info]
+ end
end
end
end
diff --git a/actionpack/test/dispatch/prefix_generation_test.rb b/actionpack/test/dispatch/prefix_generation_test.rb
index b28a058250..93eccaecbd 100644
--- a/actionpack/test/dispatch/prefix_generation_test.rb
+++ b/actionpack/test/dispatch/prefix_generation_test.rb
@@ -50,7 +50,9 @@ module TestGenerationPrefix
scope "/:omg", :omg => "awesome" do
mount BlogEngine => "/blog", :as => "blog_engine"
end
+ match "/posts/:id", :to => "outside_engine_generating#post", :as => :post
match "/generate", :to => "outside_engine_generating#index"
+ match "/polymorphic_path_for_app", :to => "outside_engine_generating#polymorphic_path_for_app"
match "/polymorphic_path_for_engine", :to => "outside_engine_generating#polymorphic_path_for_engine"
match "/polymorphic_with_url_for", :to => "outside_engine_generating#polymorphic_with_url_for"
match "/conflicting_url", :to => "outside_engine_generating#conflicting"
@@ -101,6 +103,7 @@ module TestGenerationPrefix
class ::OutsideEngineGeneratingController < ActionController::Base
include BlogEngine.routes.mounted_helpers
+ include RailsApplication.routes.url_helpers
def index
render :text => blog_engine.post_path(:id => 1)
@@ -110,6 +113,10 @@ module TestGenerationPrefix
render :text => blog_engine.polymorphic_path(Post.new)
end
+ def polymorphic_path_for_app
+ render :text => polymorphic_path(Post.new)
+ end
+
def polymorphic_with_url_for
render :text => blog_engine.url_for(Post.new)
end
@@ -201,6 +208,11 @@ module TestGenerationPrefix
assert_equal "/awesome/blog/posts/1", last_response.body
end
+ test "polymorphic_path_for_app" do
+ get "/polymorphic_path_for_app"
+ assert_equal "/posts/1", last_response.body
+ end
+
test "[APP] generating engine's url with url_for(@post)" do
get "/polymorphic_with_url_for"
assert_equal "http://example.org/awesome/blog/posts/1", last_response.body
diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb
index 25b1b4f745..060bcfb5ec 100644
--- a/actionpack/test/dispatch/request_test.rb
+++ b/actionpack/test/dispatch/request_test.rb
@@ -468,6 +468,12 @@ class RequestTest < ActiveSupport::TestCase
assert request.formats.empty?
end
+ test "formats with xhr request" do
+ request = stub_request 'HTTP_X_REQUESTED_WITH' => "XMLHttpRequest"
+ request.expects(:parameters).at_least_once.returns({})
+ assert_equal [Mime::JS], request.formats
+ end
+
test "ignore_accept_header" do
ActionDispatch::Request.ignore_accept_header = true
diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb
index ba7506721f..1938348375 100644
--- a/actionpack/test/dispatch/routing_test.rb
+++ b/actionpack/test/dispatch/routing_test.rb
@@ -504,6 +504,12 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
match '/countries/:country/(*other)', :to => redirect{ |params, req| params[:other] ? "/countries/all/#{params[:other]}" : '/countries/all' }
match '/:locale/*file.:format', :to => 'files#show', :file => /path\/to\/existing\/file/
+
+ scope '/italians' do
+ match '/writers', :to => 'italians#writers', :constraints => ::TestRoutingMapper::IpRestrictor
+ match '/sculptors', :to => 'italians#sculptors'
+ match '/painters/:painter', :to => 'italians#painters', :constraints => {:painter => /michelangelo/}
+ end
end
end
@@ -2229,6 +2235,20 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
verify_redirect 'http://www.example.com/countries/all/cities'
end
+ def test_constraints_block_not_carried_to_following_routes
+ get '/italians/writers'
+ assert_equal 'Not Found', @response.body
+
+ get '/italians/sculptors'
+ assert_equal 'italians#sculptors', @response.body
+
+ get '/italians/painters/botticelli'
+ assert_equal 'Not Found', @response.body
+
+ get '/italians/painters/michelangelo'
+ assert_equal 'italians#painters', @response.body
+ end
+
def test_custom_resource_actions_defined_using_string
get '/customers/inactive'
assert_equal 'customers#inactive', @response.body
diff --git a/actionpack/test/fixtures/test/_200.html.erb b/actionpack/test/fixtures/test/_200.html.erb
new file mode 100644
index 0000000000..c9f45675dc
--- /dev/null
+++ b/actionpack/test/fixtures/test/_200.html.erb
@@ -0,0 +1 @@
+<h1>Invalid partial</h1>
diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb
index d5bd7256f7..d93433deac 100644
--- a/actionpack/test/template/asset_tag_helper_test.rb
+++ b/actionpack/test/template/asset_tag_helper_test.rb
@@ -443,7 +443,7 @@ class AssetTagHelperTest < ActionView::TestCase
def test_image_tag_windows_behaviour
old_asset_id, ENV["RAILS_ASSET_ID"] = ENV["RAILS_ASSET_ID"], "1"
- # This simulates the behaviour of File#exist? on windows when testing a file ending in "."
+ # This simulates the behavior of File#exist? on windows when testing a file ending in "."
# If the file "rails.png" exists, windows will return true when asked if "rails.png." exists (notice trailing ".")
# OS X, linux etc will return false in this case.
File.stubs(:exist?).with('template/../fixtures/public/images/rails.png.').returns(true)
@@ -481,7 +481,7 @@ class AssetTagHelperTest < ActionView::TestCase
end
def test_timebased_asset_id
- expected_time = File.stat(File.expand_path(File.dirname(__FILE__) + "/../fixtures/public/images/rails.png")).mtime.to_i.to_s
+ expected_time = File.mtime(File.expand_path(File.dirname(__FILE__) + "/../fixtures/public/images/rails.png")).to_i.to_s
assert_equal %(<img alt="Rails" src="/images/rails.png?#{expected_time}" />), image_tag("rails.png")
end
@@ -512,7 +512,7 @@ class AssetTagHelperTest < ActionView::TestCase
def test_timebased_asset_id_with_relative_url_root
@controller.config.relative_url_root = "/collaboration/hieraki"
- expected_time = File.stat(File.expand_path(File.dirname(__FILE__) + "/../fixtures/public/images/rails.png")).mtime.to_i.to_s
+ expected_time = File.mtime(File.expand_path(File.dirname(__FILE__) + "/../fixtures/public/images/rails.png")).to_i.to_s
assert_equal %(<img alt="Rails" src="#{@controller.config.relative_url_root}/images/rails.png?#{expected_time}" />), image_tag("rails.png")
end
diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb
index 4187a0ac78..68b2ed45d1 100644
--- a/actionpack/test/template/render_test.rb
+++ b/actionpack/test/template/render_test.rb
@@ -98,6 +98,15 @@ module RenderTestCases
assert_equal "only partial", @view.render("test/partial_only", :counter_counter => 5)
end
+ def test_render_partial_with_invalid_name
+ @view.render(:partial => "test/200")
+ flunk "Render did not raise ArgumentError"
+ rescue ArgumentError => e
+ assert_equal "The partial name (test/200) is not a valid Ruby identifier; " +
+ "make sure your partial name starts with a letter or underscore, " +
+ "and is followed by any combinations of letters, numbers, or underscores.", e.message
+ end
+
def test_render_partial_with_errors
@view.render(:partial => "test/raise")
flunk "Render did not raise Template::Error"
diff --git a/actionpack/test/template/sprockets_helper_test.rb b/actionpack/test/template/sprockets_helper_test.rb
index f11d1bba15..b9161b62c5 100644
--- a/actionpack/test/template/sprockets_helper_test.rb
+++ b/actionpack/test/template/sprockets_helper_test.rb
@@ -4,33 +4,29 @@ require 'sprockets/helpers/rails_helper'
require 'mocha'
class SprocketsHelperTest < ActionView::TestCase
- tests Sprockets::Helpers::RailsHelper
+ include Sprockets::Helpers::RailsHelper
attr_accessor :assets
+ class MockRequest
+ def protocol() 'http://' end
+ def ssl?() false end
+ def host_with_port() 'localhost' end
+ end
+
def setup
super
- @controller = BasicController.new
- @controller.stubs(:params).returns({})
-
- @request = Class.new do
- def protocol() 'http://' end
- def ssl?() false end
- def host_with_port() 'localhost' end
- end.new
-
- @controller.request = @request
+ @controller = BasicController.new
+ @controller.request = MockRequest.new
@assets = Sprockets::Environment.new
- @assets.paths << FIXTURES.join("sprockets/app/javascripts")
- @assets.paths << FIXTURES.join("sprockets/app/stylesheets")
- @assets.paths << FIXTURES.join("sprockets/app/images")
+ @assets.append_path(FIXTURES.join("sprockets/app/javascripts"))
+ @assets.append_path(FIXTURES.join("sprockets/app/stylesheets"))
+ @assets.append_path(FIXTURES.join("sprockets/app/images"))
- application = Object.new
+ application = Struct.new(:config, :assets).new(config, @assets)
Rails.stubs(:application).returns(application)
- application.stubs(:config).returns(config)
- application.stubs(:assets).returns(@assets)
@config = config
@config.action_controller ||= ActiveSupport::InheritableOptions.new
@config.perform_caching = true
@@ -41,7 +37,7 @@ class SprocketsHelperTest < ActionView::TestCase
end
test "asset_path" do
- assert_equal "/assets/logo-9c0a079bdd7701d7e729bd956823d153.png",
+ assert_match %r{/assets/logo-[0-9a-f]+.png},
asset_path("logo.png")
end
@@ -54,7 +50,7 @@ class SprocketsHelperTest < ActionView::TestCase
assert_equal "/dir/audio",
asset_path("/dir/audio")
end
-
+
test "asset_path with absolute urls" do
assert_equal "http://www.example.com/video/play",
asset_path("http://www.example.com/video/play")
@@ -74,7 +70,7 @@ class SprocketsHelperTest < ActionView::TestCase
assert_match %r{http://assets-\d.example.com/assets/logo-[0-9a-f]+.png},
asset_path("logo.png")
end
-
+
test "With a proc asset host that returns no protocol the url should be protocol relative" do
@controller.config.asset_host = Proc.new do |asset|
"assets-999.example.com"
@@ -116,7 +112,7 @@ class SprocketsHelperTest < ActionView::TestCase
@config.action_controller.default_asset_host_protocol = :request
@config.action_controller.perform_caching = true
- assert_equal "/assets/logo-9c0a079bdd7701d7e729bd956823d153.png",
+ assert_match %r{/assets/logo-[0-9a-f]+.png},
asset_path("logo.png")
end
@@ -127,12 +123,12 @@ class SprocketsHelperTest < ActionView::TestCase
end
test "javascript path" do
- assert_equal "/assets/application-d41d8cd98f00b204e9800998ecf8427e.js",
+ assert_match %r{/assets/application-[0-9a-f]+.js},
asset_path(:application, "js")
- assert_equal "/assets/xmlhr-d41d8cd98f00b204e9800998ecf8427e.js",
+ assert_match %r{/assets/xmlhr-[0-9a-f]+.js},
asset_path("xmlhr", "js")
- assert_equal "/assets/dir/xmlhr-d41d8cd98f00b204e9800998ecf8427e.js",
+ assert_match %r{/assets/dir/xmlhr-[0-9a-f]+.js},
asset_path("dir/xmlhr.js", "js")
assert_equal "/dir/xmlhr.js",
@@ -145,28 +141,28 @@ class SprocketsHelperTest < ActionView::TestCase
end
test "javascript include tag" do
- assert_equal '<script src="/assets/application-d41d8cd98f00b204e9800998ecf8427e.js" type="text/javascript"></script>',
+ assert_match %r{<script src="/assets/application-[0-9a-f]+.js" type="text/javascript"></script>},
javascript_include_tag(:application)
- assert_equal '<script src="/assets/xmlhr-d41d8cd98f00b204e9800998ecf8427e.js" type="text/javascript"></script>',
+ assert_match %r{<script src="/assets/xmlhr-[0-9a-f]+.js" type="text/javascript"></script>},
javascript_include_tag("xmlhr")
- assert_equal '<script src="/assets/xmlhr-d41d8cd98f00b204e9800998ecf8427e.js" type="text/javascript"></script>',
+ assert_match %r{<script src="/assets/xmlhr-[0-9a-f]+.js" type="text/javascript"></script>},
javascript_include_tag("xmlhr.js")
assert_equal '<script src="http://www.example.com/xmlhr" type="text/javascript"></script>',
javascript_include_tag("http://www.example.com/xmlhr")
- assert_equal "<script src=\"/assets/xmlhr-d41d8cd98f00b204e9800998ecf8427e.js?body=1\" type=\"text/javascript\"></script>\n<script src=\"/assets/application-d41d8cd98f00b204e9800998ecf8427e.js?body=1\" type=\"text/javascript\"></script>",
+ assert_match %r{<script src="/assets/xmlhr-[0-9a-f]+.js\?body=1" type="text/javascript"></script>\n<script src="/assets/application-[0-9a-f]+.js\?body=1" type="text/javascript"></script>},
javascript_include_tag(:application, :debug => true)
- assert_equal "<script src=\"/assets/xmlhr-d41d8cd98f00b204e9800998ecf8427e.js\" type=\"text/javascript\"></script>\n<script src=\"/assets/extra-d41d8cd98f00b204e9800998ecf8427e.js\" type=\"text/javascript\"></script>",
+ assert_match %r{<script src=\"/assets/xmlhr-[0-9a-f]+.js\" type=\"text/javascript\"></script>\n<script src=\"/assets/extra-[0-9a-f]+.js\" type=\"text/javascript\"></script>},
javascript_include_tag("xmlhr", "extra")
end
test "stylesheet path" do
- assert_equal "/assets/application-68b329da9893e34099c7d8ad5cb9c940.css", asset_path(:application, "css")
+ assert_match %r{/assets/application-[0-9a-f]+.css}, asset_path(:application, "css")
- assert_equal "/assets/style-d41d8cd98f00b204e9800998ecf8427e.css", asset_path("style", "css")
- assert_equal "/assets/dir/style-d41d8cd98f00b204e9800998ecf8427e.css", asset_path("dir/style.css", "css")
+ assert_match %r{/assets/style-[0-9a-f]+.css}, asset_path("style", "css")
+ assert_match %r{/assets/dir/style-[0-9a-f]+.css}, asset_path("dir/style.css", "css")
assert_equal "/dir/style.css", asset_path("/dir/style.css", "css")
assert_equal "http://www.example.com/css/style",
@@ -176,37 +172,37 @@ class SprocketsHelperTest < ActionView::TestCase
end
test "stylesheet link tag" do
- assert_equal '<link href="/assets/application-68b329da9893e34099c7d8ad5cb9c940.css" media="screen" rel="stylesheet" type="text/css" />',
+ assert_match %r{<link href="/assets/application-[0-9a-f]+.css" media="screen" rel="stylesheet" type="text/css" />},
stylesheet_link_tag(:application)
- assert_equal '<link href="/assets/style-d41d8cd98f00b204e9800998ecf8427e.css" media="screen" rel="stylesheet" type="text/css" />',
+ assert_match %r{<link href="/assets/style-[0-9a-f]+.css" media="screen" rel="stylesheet" type="text/css" />},
stylesheet_link_tag("style")
- assert_equal '<link href="/assets/style-d41d8cd98f00b204e9800998ecf8427e.css" media="screen" rel="stylesheet" type="text/css" />',
+ assert_match %r{<link href="/assets/style-[0-9a-f]+.css" media="screen" rel="stylesheet" type="text/css" />},
stylesheet_link_tag("style.css")
assert_equal '<link href="http://www.example.com/style.css" media="screen" rel="stylesheet" type="text/css" />',
stylesheet_link_tag("http://www.example.com/style.css")
- assert_equal '<link href="/assets/style-d41d8cd98f00b204e9800998ecf8427e.css" media="all" rel="stylesheet" type="text/css" />',
+ assert_match %r{<link href="/assets/style-[0-9a-f]+.css" media="all" rel="stylesheet" type="text/css" />},
stylesheet_link_tag("style", :media => "all")
- assert_equal '<link href="/assets/style-d41d8cd98f00b204e9800998ecf8427e.css" media="print" rel="stylesheet" type="text/css" />',
+ assert_match %r{<link href="/assets/style-[0-9a-f]+.css" media="print" rel="stylesheet" type="text/css" />},
stylesheet_link_tag("style", :media => "print")
- assert_equal "<link href=\"/assets/style-d41d8cd98f00b204e9800998ecf8427e.css?body=1\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\" />\n<link href=\"/assets/application-68b329da9893e34099c7d8ad5cb9c940.css?body=1\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\" />",
+ assert_match %r{<link href="/assets/style-[0-9a-f]+.css\?body=1" media="screen" rel="stylesheet" type="text/css" />\n<link href="/assets/application-[0-9a-f]+.css\?body=1" media="screen" rel="stylesheet" type="text/css" />},
stylesheet_link_tag(:application, :debug => true)
- assert_equal "<link href=\"/assets/style-d41d8cd98f00b204e9800998ecf8427e.css\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\" />\n<link href=\"/assets/extra-d41d8cd98f00b204e9800998ecf8427e.css\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\" />",
+ assert_match %r{<link href="/assets/style-[0-9a-f]+.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/assets/extra-[0-9a-f]+.css" media="screen" rel="stylesheet" type="text/css" />},
stylesheet_link_tag("style", "extra")
end
test "alternate asset prefix" do
stubs(:asset_prefix).returns("/themes/test")
- assert_equal "/themes/test/style-d41d8cd98f00b204e9800998ecf8427e.css", asset_path("style", "css")
+ assert_match %r{/themes/test/style-[0-9a-f]+.css}, asset_path("style", "css")
end
test "alternate asset environment" do
assets = Sprockets::Environment.new
- assets.paths << FIXTURES.join("sprockets/alternate/stylesheets")
+ assets.append_path(FIXTURES.join("sprockets/alternate/stylesheets"))
stubs(:asset_environment).returns(assets)
- assert_equal "/assets/style-df0b97ad35a8e1f7f61097461f77c19a.css", asset_path("style", "css")
+ assert_match %r{/assets/style-[0-9a-f]+.css}, asset_path("style", "css")
end
end
diff --git a/actionpack/test/template/test_test.rb b/actionpack/test/template/test_test.rb
index 3d0bbba435..bf789cd8b7 100644
--- a/actionpack/test/template/test_test.rb
+++ b/actionpack/test/template/test_test.rb
@@ -39,7 +39,7 @@ class PeopleHelperTest < ActionView::TestCase
with_test_route_set do
person = mock(:name => "David")
person.class.extend ActiveModel::Naming
- _routes.url_helpers.expects(:hash_for_mocha_mock_path).with(person).returns("/people/1")
+ expects(:mocha_mock_path).with(person).returns("/people/1")
assert_equal '<a href="/people/1">David</a>', link_to_person(person)
end
end
diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb
index a70c02a429..78245c1f95 100644
--- a/actionpack/test/template/url_helper_test.rb
+++ b/actionpack/test/template/url_helper_test.rb
@@ -386,13 +386,11 @@ class UrlHelperTest < ActiveSupport::TestCase
def test_mail_to_with_javascript
snippet = mail_to("me@domain.com", "My email", :encode => "javascript")
assert_dom_equal "<script type=\"text/javascript\">eval(decodeURIComponent('%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%61%20%68%72%65%66%3d%5c%22%6d%61%69%6c%74%6f%3a%6d%65%40%64%6f%6d%61%69%6e%2e%63%6f%6d%5c%22%3e%4d%79%20%65%6d%61%69%6c%3c%5c%2f%61%3e%27%29%3b'))</script>", snippet
- assert snippet.html_safe?
end
def test_mail_to_with_javascript_unicode
snippet = mail_to("unicode@example.com", "Ășnicode", :encode => "javascript")
assert_dom_equal "<script type=\"text/javascript\">eval(decodeURIComponent('%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%61%20%68%72%65%66%3d%5c%22%6d%61%69%6c%74%6f%3a%75%6e%69%63%6f%64%65%40%65%78%61%6d%70%6c%65%2e%63%6f%6d%5c%22%3e%c3%ba%6e%69%63%6f%64%65%3c%5c%2f%61%3e%27%29%3b'))</script>", snippet
- assert snippet.html_safe
end
def test_mail_with_options
@@ -421,6 +419,12 @@ class UrlHelperTest < ActiveSupport::TestCase
assert_dom_equal "<script type=\"text/javascript\">eval(decodeURIComponent('%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%61%20%68%72%65%66%3d%5c%22%6d%61%69%6c%74%6f%3a%6d%65%40%64%6f%6d%61%69%6e%2e%63%6f%6d%5c%22%3e%6d%65%28%61%74%29%64%6f%6d%61%69%6e%28%64%6f%74%29%63%6f%6d%3c%5c%2f%61%3e%27%29%3b'))</script>", mail_to("me@domain.com", nil, :encode => "javascript", :replace_at => "(at)", :replace_dot => "(dot)")
end
+ def test_mail_to_returns_html_safe_string
+ assert mail_to("david@loudthinking.com").html_safe?
+ assert mail_to("me@domain.com", "My email", :encode => "javascript").html_safe?
+ assert mail_to("me@domain.com", "My email", :encode => "hex").html_safe?
+ end
+
# TODO: button_to looks at this ... why?
def protect_against_forgery?
false