aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2005-03-06 11:50:41 +0000
committerDavid Heinemeier Hansson <david@loudthinking.com>2005-03-06 11:50:41 +0000
commitdfac1cea3d851000116a23ab14c2b1ae981f7a12 (patch)
tree91abe3727d19f4c13affe1a2e4bc4637b35d5fdf
parentdb41d2dd5c738ca44a07330cf02e9d817fedc34c (diff)
downloadrails-dfac1cea3d851000116a23ab14c2b1ae981f7a12.tar.gz
rails-dfac1cea3d851000116a23ab14c2b1ae981f7a12.tar.bz2
rails-dfac1cea3d851000116a23ab14c2b1ae981f7a12.zip
Fixed that form helpers would treat string and symbol keys differently in html_options (and possibly create duplicate entries) #112 [bitsweat]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@833 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
-rw-r--r--actionpack/CHANGELOG2
-rw-r--r--actionpack/lib/action_view/helpers/active_record_helper.rb28
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helper.rb12
-rwxr-xr-xactionpack/lib/action_view/helpers/date_helper.rb52
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb128
-rw-r--r--actionpack/lib/action_view/helpers/form_options_helper.rb50
-rw-r--r--actionpack/lib/action_view/helpers/form_tag_helper.rb36
-rw-r--r--actionpack/lib/action_view/helpers/tag_helper.rb8
-rw-r--r--actionpack/lib/action_view/helpers/text_helper.rb22
-rw-r--r--actionpack/lib/action_view/helpers/url_helper.rb39
-rw-r--r--actionpack/test/template/active_record_helper_test.rb2
-rw-r--r--actionpack/test/template/form_helper_test.rb57
-rw-r--r--actionpack/test/template/form_options_helper_test.rb24
-rw-r--r--actionpack/test/template/form_tag_helper_test.rb5
-rw-r--r--actionpack/test/template/tag_helper_test.rb13
-rw-r--r--actionpack/test/template/text_helper_test.rb14
-rw-r--r--actionpack/test/template/url_helper_test.rb23
17 files changed, 283 insertions, 232 deletions
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG
index b901012044..18ea6b9b4c 100644
--- a/actionpack/CHANGELOG
+++ b/actionpack/CHANGELOG
@@ -1,5 +1,7 @@
*SVN*
+* Fixed that form helpers would treat string and symbol keys differently in html_options (and possibly create duplicate entries) #112 [bitsweat]
+
* Fixed that broken pipe errors (clients disconnecting in mid-request) could bring down a fcgi process
* Added the original exception message to session recall errors (so you can see which class wasnt required)
diff --git a/actionpack/lib/action_view/helpers/active_record_helper.rb b/actionpack/lib/action_view/helpers/active_record_helper.rb
index 45a5aff8bd..090ca33cef 100644
--- a/actionpack/lib/action_view/helpers/active_record_helper.rb
+++ b/actionpack/lib/action_view/helpers/active_record_helper.rb
@@ -15,7 +15,7 @@ module ActionView
module ActiveRecordHelper
# Returns a default input tag for the type of object returned by the method. Example
# (title is a VARCHAR column and holds "Hello World"):
- # input("post", "title") =>
+ # input("post", "title") =>
# <input id="post_title" name="post[title]" size="30" type="text" value="Hello World" />
def input(record_name, method)
InstanceTag.new(record_name, method, self).to_tag
@@ -41,7 +41,7 @@ module ActionView
# It's possible to specialize the form builder by using a different action name and by supplying another
# block renderer. Example (entry is a new record that has a message attribute using VARCHAR):
#
- # form("entry", :action => "sign", :input_block =>
+ # form("entry", :action => "sign", :input_block =>
# Proc.new { |record, column| "#{column.human_name}: #{input(record, column.name)}<br />" }) =>
#
# <form action='/post/sign' method='post'>
@@ -56,16 +56,17 @@ module ActionView
# form << content_tag("b", "Department")
# form << collection_select("department", "id", @departments, "id", "name")
# end
- def form(record_name, options = {})
- record = instance_eval("@#{record_name}")
+ def form(record_name, options = nil)
+ options = (options || {}).symbolize_keys
+ record = instance_eval("@#{record_name}")
options[:action] ||= record.new_record? ? "create" : "update"
- action = url_for(:action => options[:action])
+ action = url_for(:action => options[:action])
submit_value = options[:submit_value] || options[:action].gsub(/[^\w]/, '').capitalize
-
+
id_field = record.new_record? ? "" : InstanceTag.new(record_name, "id", self).to_input_field_tag("hidden")
-
+
formtag = %(<form action="#{action}" method="post">#{id_field}) + all_input_tags(record, record_name, options)
yield formtag if block_given?
formtag + %(<input type="submit" value="#{submit_value}" /></form>)
@@ -73,7 +74,7 @@ module ActionView
# Returns a string containing the error message attached to the +method+ on the +object+, if one exists.
# This error message is wrapped in a DIV tag, which can be specialized to include both a +prepend_text+ and +append_text+
- # to properly introduce the error and a +css_class+ to style it accordingly. Examples (post has an error message
+ # to properly introduce the error and a +css_class+ to style it accordingly. Examples (post has an error message
# "can't be empty" on the title attribute):
#
# <%= error_message_on "post", "title" %> =>
@@ -86,19 +87,20 @@ module ActionView
"<div class=\"#{css_class}\">#{prepend_text + (errors.is_a?(Array) ? errors.first : errors) + append_text}</div>"
end
end
-
+
# Returns a string with a div containing all the error messages for the object located as an instance variable by the name
# of <tt>object_name</tt>. This div can be tailored by the following options:
#
# * <tt>header_tag</tt> - Used for the header of the error div (default: h2)
# * <tt>id</tt> - The id of the error div (default: errorExplanation)
# * <tt>class</tt> - The class of the error div (default: errorExplanation)
- def error_messages_for(object_name, options={})
+ def error_messages_for(object_name, options = {})
+ options = options.symbolize_keys
object = instance_eval "@#{object_name}"
unless object.errors.empty?
content_tag("div",
content_tag(
- options[:header_tag] || "h2",
+ options[:header_tag] || "h2",
"#{pluralize(object.errors.count, "error")} prohibited this #{object_name.gsub("_", " ")} from being saved"
) +
content_tag("p", "There were problems with the following fields:") +
@@ -107,7 +109,7 @@ module ActionView
)
end
end
-
+
private
def all_input_tags(record, record_name, options)
input_block = options[:input_block] || default_input_block
@@ -116,7 +118,7 @@ module ActionView
def default_input_block
Proc.new { |record, column| "<p><label for=\"#{record}_#{column.name}\">#{column.human_name}</label><br />#{input(record, column.name)}</p>" }
- end
+ end
end
class InstanceTag #:nodoc:
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
index 33914b2144..2f3bd71d5a 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -10,15 +10,15 @@ module ActionView
# either be <tt>:rss</tt> (default) or <tt>:atom</tt> and the +options+ follow the url_for style of declaring a link target.
#
# Examples:
- # auto_discovery_link_tag # =>
+ # auto_discovery_link_tag # =>
# <link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.curenthost.com/controller/action" />
- # auto_discovery_link_tag(:atom) # =>
+ # auto_discovery_link_tag(:atom) # =>
# <link rel="alternate" type="application/atom+xml" title="ATOM" href="http://www.curenthost.com/controller/action" />
- # auto_discovery_link_tag(:rss, :action => "feed") # =>
+ # auto_discovery_link_tag(:rss, :action => "feed") # =>
# <link rel="alternate" type="application/atom+xml" title="ATOM" href="http://www.curenthost.com/controller/feed" />
def auto_discovery_link_tag(type = :rss, options = {})
tag(
- "link", "rel" => "alternate", "type" => "application/#{type}+xml", "title" => type.to_s.upcase,
+ "link", "rel" => "alternate", "type" => "application/#{type}+xml", "title" => type.to_s.upcase,
"href" => url_for(options.merge(:only_path => false))
)
end
@@ -38,7 +38,7 @@ module ActionView
content_tag("script", "", "language" => "JavaScript", "type" => "text/javascript", "src" => source)
}.join("\n")
end
-
+
# Returns a css link tag per source given as argument. Examples:
#
# stylesheet_link_tag "style" # =>
@@ -48,7 +48,7 @@ module ActionView
# <link href="/stylesheets/random.styles" media="screen" rel="Stylesheet" type="text/css" />
# <link href="/css/stylish.css" media="screen" rel="Stylesheet" type="text/css" />
def stylesheet_link_tag(*sources)
- sources.collect { |source|
+ sources.collect { |source|
source = "/stylesheets/#{source}" unless source.include?("/")
source = "#{source}.css" unless source.include?(".")
tag("link", "rel" => "Stylesheet", "type" => "text/css", "media" => "screen", "href" => source)
diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb
index 03a34c93f1..7ec24f2428 100755
--- a/actionpack/lib/action_view/helpers/date_helper.rb
+++ b/actionpack/lib/action_view/helpers/date_helper.rb
@@ -5,7 +5,7 @@ module ActionView
# 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:
#
- # * <tt>:prefix</tt> - overwrites the default prefix of "date" used for the select names. So specifying "birthday" would give
+ # * <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 select_month method.
# * <tt>:include_blank</tt> - set to true if it should be possible to set an empty date.
# * <tt>:discard_type</tt> - set to true if you want to discard the type part of the select name. If set to true, the select_month
@@ -13,11 +13,11 @@ module ActionView
module DateHelper
DEFAULT_PREFIX = "date" unless const_defined?("DEFAULT_PREFIX")
- # Reports the approximate distance in time between to Time objects. For example, if the distance is 47 minutes, it'll return
+ # Reports the approximate distance in time between to Time objects. For example, if the distance is 47 minutes, it'll return
# "about 1 hour". See the source for the complete wording list.
def distance_of_time_in_words(from_time, to_time)
distance_in_minutes = ((to_time - from_time) / 60).round
-
+
case distance_in_minutes
when 0 then "less than a minute"
when 1 then "1 minute"
@@ -28,7 +28,7 @@ module ActionView
else "#{(distance_in_minutes / 1440).round} days"
end
end
-
+
# Like distance_of_time_in_words, but where <tt>to_time</tt> is fixed to <tt>Time.now</tt>.
def distance_of_time_in_words_to_now(from_time)
distance_of_time_in_words(from_time, Time.now)
@@ -48,7 +48,7 @@ module ActionView
#
# date_select("post", "written_on")
# date_select("post", "written_on", :start_year => 1995)
- # date_select("post", "written_on", :start_year => 1995, :use_month_numbers => true,
+ # date_select("post", "written_on", :start_year => 1995, :use_month_numbers => true,
# :discard_day => true, :include_blank => true)
# date_select("post", "written_on", :order => [:day, :month, :year])
# date_select("user", "birthday", :order => [:month, :day])
@@ -107,7 +107,7 @@ module ActionView
0.upto(59) do |minute|
minute_options << ((datetime.kind_of?(Fixnum) ? datetime : datetime.min) == minute ?
- "<option selected=\"selected\">#{leading_zero_on_single_digits(minute)}</option>\n" :
+ "<option selected=\"selected\">#{leading_zero_on_single_digits(minute)}</option>\n" :
"<option>#{leading_zero_on_single_digits(minute)}</option>\n"
)
end
@@ -122,7 +122,7 @@ module ActionView
0.upto(23) do |hour|
hour_options << ((datetime.kind_of?(Fixnum) ? datetime : datetime.hour) == hour ?
- "<option selected=\"selected\">#{leading_zero_on_single_digits(hour)}</option>\n" :
+ "<option selected=\"selected\">#{leading_zero_on_single_digits(hour)}</option>\n" :
"<option>#{leading_zero_on_single_digits(hour)}</option>\n"
)
end
@@ -137,18 +137,18 @@ module ActionView
1.upto(31) do |day|
day_options << ((date.kind_of?(Fixnum) ? date : date.day) == day ?
- "<option selected=\"selected\">#{day}</option>\n" :
+ "<option selected=\"selected\">#{day}</option>\n" :
"<option>#{day}</option>\n"
)
end
select_html("day", day_options, options[:prefix], options[:include_blank], options[:discard_type])
end
-
+
# Returns a select tag with options for each of the months January through December with the current month selected.
# The month names are presented as keys (what's shown to the user) and the month numbers (1-12) are used as values
# (what's submitted to the server). It's also possible to use month numbers for the presentation instead of names --
- # set the <tt>:use_month_numbers</tt> key in +options+ to true for this to happen. If you want both numbers and names,
+ # set the <tt>:use_month_numbers</tt> key in +options+ to true for this to happen. If you want both numbers and names,
# set the <tt>:add_month_numbers</tt> key in +options+ to true. Examples:
#
# select_month(Date.today) # Will use keys like "January", "March"
@@ -158,7 +158,7 @@ module ActionView
month_options = []
1.upto(12) do |month_number|
- month_name = if options[:use_month_numbers]
+ month_name = if options[:use_month_numbers]
month_number
elsif options[:add_month_numbers]
month_number.to_s + " - " + Date::MONTHNAMES[month_number]
@@ -167,16 +167,16 @@ module ActionView
end
month_options << ((date.kind_of?(Fixnum) ? date : date.month) == month_number ?
- %(<option value="#{month_number}" selected="selected">#{month_name}</option>\n) :
+ %(<option value="#{month_number}" selected="selected">#{month_name}</option>\n) :
%(<option value="#{month_number}">#{month_name}</option>\n)
)
end
select_html("month", month_options, options[:prefix], options[:include_blank], options[:discard_type])
end
-
+
# Returns a select tag with options for each of the five years on each side of the current, which is selected. The five year radius
- # can be changed using the <tt>:start_year</tt> and <tt>:end_year</tt> keys in the +options+. The <tt>date</tt> can also be substituted
+ # can be changed using the <tt>:start_year</tt> and <tt>:end_year</tt> keys in the +options+. The <tt>date</tt> can also be substituted
# for a year given as a number. Example:
#
# select_year(Date.today, :start_year => 1992, :end_year => 2007)
@@ -187,14 +187,14 @@ module ActionView
(options[:start_year] || default_start_year).upto(options[:end_year] || default_end_year) do |year|
year_options << ((date.kind_of?(Fixnum) ? date : date.year) == year ?
- "<option selected=\"selected\">#{year}</option>\n" :
+ "<option selected=\"selected\">#{year}</option>\n" :
"<option>#{year}</option>\n"
)
end
select_html("year", year_options, options[:prefix], options[:include_blank], options[:discard_type])
end
-
+
private
def select_html(type, options, prefix = nil, include_blank = false, discard_type = false)
select_html = %(<select name="#{prefix || DEFAULT_PREFIX})
@@ -206,7 +206,7 @@ module ActionView
return select_html
end
-
+
def leading_zero_on_single_digits(number)
number > 9 ? number : "0#{number}"
end
@@ -217,32 +217,32 @@ module ActionView
def to_date_select_tag(options = {})
defaults = { :discard_type => true }
- options = defaults.merge(options)
- options_with_prefix = Proc.new { |position| options.update({ :prefix => "#{@object_name}[#{@method_name}(#{position}i)]" }) }
+ options = defaults.merge(options)
+ options_with_prefix = Proc.new { |position| options.merge(:prefix => "#{@object_name}[#{@method_name}(#{position}i)]") }
date = options[:include_blank] ? (value || 0) : (value || Date.today)
- date_select = ""
+ date_select = ""
options[:order] = [:month, :year, :day] if options[:month_before_year] # For backwards compatibility
options[:order] ||= [:year, :month, :day]
position = {:year => 1, :month => 2, :day => 3}
-
+
discard = {}
discard[:year] = true if options[:discard_year]
discard[:month] = true if options[:discard_month]
discard[:day] = true if options[:discard_day] or options[:discard_month]
-
+
options[:order].each do |param|
date_select << self.send("select_#{param}", date, options_with_prefix.call(position[param])) unless discard[param]
end
return date_select
end
-
+
def to_datetime_select_tag(options = {})
defaults = { :discard_type => true }
- options = defaults.merge(options)
- options_with_prefix = Proc.new { |position| options.update({ :prefix => "#{@object_name}[#{@method_name}(#{position}i)]" }) }
+ options = defaults.merge(options)
+ options_with_prefix = Proc.new { |position| options.merge(:prefix => "#{@object_name}[#{@method_name}(#{position}i)]") }
datetime = options[:include_blank] ? (value || 0) : (value || Time.now)
datetime_select = select_year(datetime, options_with_prefix.call(1))
@@ -250,7 +250,7 @@ module ActionView
datetime_select << select_day(datetime, options_with_prefix.call(3)) unless options[:discard_day] || options[:discard_month]
datetime_select << " &mdash; " + select_hour(datetime, options_with_prefix.call(4)) unless options[:discard_hour]
datetime_select << " : " + select_minute(datetime, options_with_prefix.call(5)) unless options[:discard_minute] || options[:discard_hour]
-
+
return datetime_select
end
end
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index 2c9589194c..e4b90e42f2 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -8,10 +8,10 @@ module ActionView
# The following is an example of a complete form for a person object that works for both creates and updates built
# with all the form helpers. The <tt>@person</tt> object was assigned by an action on the controller:
# <form action="save_person" method="post">
- # Name:
+ # Name:
# <%= text_field "person", "name", "size" => 20 %>
#
- # Password:
+ # Password:
# <%= password_field "person", "password", "maxsize" => 20 %>
#
# Single?:
@@ -26,12 +26,12 @@ module ActionView
# ...is compiled to:
#
# <form action="save_person" method="post">
- # Name:
- # <input type="text" id="person_name" name="person[name]"
+ # Name:
+ # <input type="text" id="person_name" name="person[name]"
# size="20" value="<%= @person.name %>" />
#
- # Password:
- # <input type="password" id="person_password" name="person[password]"
+ # Password:
+ # <input type="password" id="person_password" name="person[password]"
# size="20" maxsize="20" value="<%= @person.password %>" />
#
# Single?:
@@ -43,7 +43,7 @@ module ActionView
# </textarea>
#
# <input type="submit" value="Save">
- # </form>
+ # </form>
#
# If the helper is being used to generate a repetitive sequence of similar form elements, for example in a partial
# used by render_collection_of_partials, the "index" option may come in handy. Example:
@@ -51,10 +51,10 @@ module ActionView
# <%= text_field "person", "name", "index" => 1 %>
#
# becomes
- #
+ #
# <input type="text" id="person_1_name" name="person[1][name]" value="<%= @person.name %>" />
#
- # There's also methods for helping to build form tags in link:classes/ActionView/Helpers/FormOptionsHelper.html,
+ # There's also methods for helping to build form tags in link:classes/ActionView/Helpers/FormOptionsHelper.html,
# link:classes/ActionView/Helpers/DateHelper.html, and link:classes/ActionView/Helpers/ActiveRecordHelper.html
module FormHelper
# Returns an input tag of the "text" type tailored for accessing a specified attribute (identified by +method+) on an object
@@ -64,7 +64,7 @@ module ActionView
# Examples (call, result):
# text_field("post", "title", "size" => 20)
# <input type="text" id="post_title" name="post[title]" size="20" value="#{@post.title}" />
- def text_field(object, method, options = {})
+ def text_field(object, method, options = {})
InstanceTag.new(object, method, self).to_input_field_tag("text", options)
end
@@ -95,12 +95,12 @@ module ActionView
def text_area(object, method, options = {})
InstanceTag.new(object, method, self).to_text_area_tag(options)
end
-
+
# Returns a checkbox tag tailored for accessing a specified attribute (identified by +method+) on an object
# assigned to the template (identified by +object+). It's intended that +method+ returns an integer and if that
# integer is above zero, then the checkbox is checked. Additional options on the input tag can be passed as a
# hash with +options+. The +checked_value+ defaults to 1 while the default +unchecked_value+
- # is set to 0 which is convenient for boolean values. Usually unchecked checkboxes don't post anything.
+ # is set to 0 which is convenient for boolean values. Usually unchecked checkboxes don't post anything.
# We work around this problem by adding a hidden value with the same name as the checkbox.
#
# Example (call, result). Imagine that @post.validated? returns 1:
@@ -119,13 +119,13 @@ module ActionView
# Returns a radio button tag for accessing a specified attribute (identified by +method+) on an object
# assigned to the template (identified by +object+). If the current value of +method+ is +tag_value+ the
# radio button will be checked. Additional options on the input tag can be passed as a
- # hash with +options+.
+ # hash with +options+.
# Example (call, result). Imagine that @post.category returns "rails":
# radio_button("post", "category", "rails")
# radio_button("post", "category", "java")
# <input type="radio" id="post_category" name="post[category] value="rails" checked="checked" />
# <input type="radio" id="post_category" name="post[category] value="java" />
- #
+ #
def radio_button(object, method, tag_value, options = {})
InstanceTag.new(object, method, self).to_radio_button_tag(tag_value, options)
end
@@ -135,9 +135,10 @@ module ActionView
include Helpers::TagHelper
attr_reader :method_name, :object_name
-
- DEFAULT_FIELD_OPTIONS = { "size" => 30 } unless const_defined?("DEFAULT_FIELD_OPTIONS")
- DEFAULT_TEXT_AREA_OPTIONS = { "wrap" => "virtual", "cols" => 40, "rows" => 20 } unless const_defined?("DEFAULT_TEXT_AREA_OPTIONS")
+
+ DEFAULT_FIELD_OPTIONS = { "size" => 30 }.freeze unless const_defined?(:DEFAULT_FIELD_OPTIONS)
+ DEFAULT_TEXT_AREA_OPTIONS = { "wrap" => "virtual", "cols" => 40, "rows" => 20 }.freeze unless const_defined?(:DEFAULT_TEXT_AREA_OPTIONS)
+ DEFAULT_DATE_OPTIONS = { :discard_type => true }.freeze unless const_defined?(:DEFAULT_DATE_OPTIONS)
def initialize(object_name, method_name, template_object, local_binding = nil)
@object_name, @method_name = object_name, method_name
@@ -146,50 +147,69 @@ module ActionView
@auto_index = @template_object.instance_variable_get("@#{Regexp.last_match.pre_match}").id
end
end
-
+
def to_input_field_tag(field_type, options = {})
- html_options = DEFAULT_FIELD_OPTIONS.merge(options)
- html_options.merge!({ "size" => options["maxlength"]}) if options["maxlength"] && !options["size"]
- html_options.delete("size") if field_type == "hidden"
- html_options.merge!({ "type" => field_type})
- html_options.merge!({ "value" => value_before_type_cast }) if options["value"].nil? && field_type != "file"
- add_default_name_and_id(html_options)
- tag("input", html_options)
- end
-
- def to_radio_button_tag(tag_value, options={})
- html_options = DEFAULT_FIELD_OPTIONS.merge(options)
- html_options.merge!({ "checked" => "checked" }) if value == tag_value
- html_options.merge!({ "type" => "radio", "value"=> tag_value.to_s })
-
- add_default_name_and_id(html_options)
- tag("input", html_options)
- end
-
+ options = options.stringify_keys
+ if field_type == "hidden"
+ options.delete("size")
+ else
+ options["size"] ||= options["maxlength"] || DEFAULT_FIELD_OPTIONS["size"]
+ end
+ options["type"] = field_type
+ options["value"] ||= value_before_type_cast unless field_type == "file"
+ add_default_name_and_id(options)
+ tag("input", options)
+ end
+
+ def to_radio_button_tag(tag_value, options = {})
+ options = DEFAULT_FIELD_OPTIONS.merge(options.stringify_keys)
+ options["type"] = "radio"
+ options["value"] = tag_value
+ options["checked"] = "checked" if value == tag_value
+ add_default_name_and_id(options)
+ tag("input", options)
+ end
+
def to_text_area_tag(options = {})
- options = DEFAULT_TEXT_AREA_OPTIONS.merge(options)
+ options = DEFAULT_TEXT_AREA_OPTIONS.merge(options.stringify_keys)
add_default_name_and_id(options)
content_tag("textarea", html_escape(value_before_type_cast), options)
end
def to_check_box_tag(options = {}, checked_value = "1", unchecked_value = "0")
- options.merge!({ "checked" => "checked" }) if !value.nil? && ((value.is_a?(TrueClass) || value.is_a?(FalseClass)) ? value : value.to_i > 0)
- options.merge!({ "type" => "checkbox", "value" => checked_value })
+ options = options.stringify_keys
+ options["type"] = "checkbox"
+ options["value"] = checked_value
+ checked = case value
+ when TrueClass, FalseClass
+ value
+ when NilClass
+ false
+ when Integer
+ value != 0
+ else
+ value.to_i != 0
+ end
+ if checked
+ options["checked"] = "checked"
+ else
+ options.delete("checked")
+ end
add_default_name_and_id(options)
- tag("input", options) << tag("input", ({ "name" => options['name'], "type" => "hidden", "value" => unchecked_value }))
+ tag("input", options) << tag("input", "name" => options["name"], "type" => "hidden", "value" => unchecked_value)
end
def to_date_tag()
- defaults = { "discard_type" => true }
+ defaults = DEFAULT_DATE_OPTIONS.dup
date = value || Date.today
- options = Proc.new { |position| defaults.update({ :prefix => "#{@object_name}[#{@method_name}(#{position}i)]" }) }
-
+ options = Proc.new { |position| defaults.merge(:prefix => "#{@object_name}[#{@method_name}(#{position}i)]") }
html_day_select(date, options.call(3)) +
- html_month_select(date, options.call(2)) +
+ html_month_select(date, options.call(2)) +
html_year_select(date, options.call(1))
end
def to_boolean_select_tag(options = {})
+ options = options.stringify_keys
add_default_name_and_id(options)
tag_text = "<select"
tag_text << tag_options(options)
@@ -210,7 +230,7 @@ module ActionView
def value_before_type_cast
unless object.nil?
- object.respond_to?(@method_name + "_before_type_cast") ?
+ object.respond_to?(@method_name + "_before_type_cast") ?
object.send(@method_name + "_before_type_cast") :
object.send(@method_name)
end
@@ -218,23 +238,23 @@ module ActionView
private
def add_default_name_and_id(options)
- if options.has_key? "index"
- options['name'] = tag_name_with_index(options["index"]) unless options.has_key? "name"
- options['id'] = tag_id_with_index(options["index"]) unless options.has_key? "id"
+ if options.has_key?("index")
+ options["name"] ||= tag_name_with_index(options["index"])
+ options["id"] ||= tag_id_with_index(options["index"])
options.delete("index")
elsif @auto_index
- options['name'] = tag_name_with_index(@auto_index) unless options.has_key? "name"
- options['id'] = tag_id_with_index(@auto_index) unless options.has_key? "id"
+ options["name"] ||= tag_name_with_index(@auto_index)
+ options["id"] ||= tag_id_with_index(@auto_index)
else
- options['name'] = tag_name unless options.has_key? "name"
- options['id'] = tag_id unless options.has_key? "id"
+ options["name"] ||= tag_name
+ options["id"] ||= tag_id
end
end
-
+
def tag_name
"#{@object_name}[#{@method_name}]"
end
-
+
def tag_name_with_index(index)
"#{@object_name}[#{index}][#{@method_name}]"
end
diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb
index aeef3bba74..99114b8694 100644
--- a/actionpack/lib/action_view/helpers/form_options_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_options_helper.rb
@@ -25,7 +25,7 @@ module ActionView
# Create a select tag and a series of contained option tags for the provided object and method.
# The option currently held by the object will be selected, provided that the object is available.
- #
+ #
# This can be used to provide a default set of options in the standard way: before rendering the create form, a
# new model instance is assigned the default options and bound to @model_name. Usually this model is not saved
# to the database. Instead, a second model object is created when the create request is received.
@@ -34,17 +34,17 @@ module ActionView
def select(object, method, choices, options = {}, html_options = {})
InstanceTag.new(object, method, self).to_select_tag(choices, options, html_options)
end
-
+
# Return select and option tags for the given object and method using options_from_collection_for_select to generate the list of option tags.
def collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
InstanceTag.new(object, method, self).to_collection_select_tag(collection, value_method, text_method, options, html_options)
end
-
+
# Return select and option tags for the given object and method, using country_options_for_select to generate the list of option tags.
def country_select(object, method, priority_countries = nil, options = {}, html_options = {})
InstanceTag.new(object, method, self).to_country_select_tag(priority_countries, options, html_options)
end
-
+
# Return select and option tags for the given object and method, using
# #time_zone_options_for_select to generate the list of option tags.
#
@@ -57,11 +57,11 @@ module ActionView
InstanceTag.new(object, method, self).to_time_zone_select_tag(priority_zones, options, html_options)
end
- # Accepts a container (hash, array, enumerable, your type) and returns a string of option tags. Given a container
+ # Accepts a container (hash, array, enumerable, your type) and returns a string of option tags. Given a container
# where the elements respond to first and last (such as a two-element array), the "lasts" serve as option values and
# the "firsts" as option text. Hashes are turned into this form automatically, so the keys become "firsts" and values
# become lasts. If +selected+ is specified, the matching "last" or element will get the selected option-tag. +Selected+
- # may also be an array of values to be selected when using a multiple select.
+ # may also be an array of values to be selected when using a multiple select.
#
# Examples (call, result):
# options_for_select([["Dollar", "$"], ["Kroner", "DKK"]])
@@ -79,8 +79,8 @@ module ActionView
# NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag.
def options_for_select(container, selected = nil)
container = container.to_a if Hash === container
-
- options_for_select = container.inject([]) do |options, element|
+
+ options_for_select = container.inject([]) do |options, element|
if element.respond_to?(:first) && element.respond_to?(:last)
is_selected = ( (selected.respond_to?(:include?) ? selected.include?(element.last) : element.last == selected) )
if is_selected
@@ -93,11 +93,11 @@ module ActionView
options << ((is_selected) ? "<option selected=\"selected\">#{html_escape(element.to_s)}</option>" : "<option>#{html_escape(element.to_s)}</option>")
end
end
-
+
options_for_select.join("\n")
end
- # Returns a string of option tags that has been compiled by iterating over the +collection+ and assigning the
+ # Returns a string of option tags that has been compiled by iterating over the +collection+ and assigning the
# the result of a call to the +value_method+ as the option value and the +text_method+ as the option text.
# If +selected_value+ is specified, the element returning a match on +value_method+ will get the selected option tag.
#
@@ -108,7 +108,7 @@ module ActionView
# NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag.
def options_from_collection_for_select(collection, value_method, text_method, selected_value = nil)
options_for_select(
- collection.inject([]) { |options, object| options << [ object.send(text_method), object.send(value_method) ] },
+ collection.inject([]) { |options, object| options << [ object.send(text_method), object.send(value_method) ] },
selected_value
)
end
@@ -135,18 +135,18 @@ module ActionView
#
# with objects of the following classes:
# class Continent
- # def initialize(p_name, p_countries) @continent_name = p_name; @countries = p_countries; end
- # def continent_name() @continent_name; end
- # def countries() @countries; end
+ # def initialize(p_name, p_countries) @continent_name = p_name; @countries = p_countries; end
+ # def continent_name() @continent_name; end
+ # def countries() @countries; end
# end
# class Country
- # def initialize(id, name) @id = id; @name = name end
- # def country_id() @id; end
- # def country_name() @name; end
+ # def initialize(id, name) @id = id; @name = name end
+ # def country_id() @id; end
+ # def country_name() @name; end
# end
#
# NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag.
- def option_groups_from_collection_for_select(collection, group_method, group_label_method,
+ def option_groups_from_collection_for_select(collection, group_method, group_label_method,
option_key_method, option_value_method, selected_key = nil)
collection.inject("") do |options_for_select, group|
group_label_string = eval("group.#{group_label_method}")
@@ -154,16 +154,16 @@ module ActionView
options_for_select += options_from_collection_for_select(eval("group.#{group_method}"), option_key_method, option_value_method, selected_key)
options_for_select += '</optgroup>'
end
- end
-
- # Returns a string of option tags for pretty much any country in the world. Supply a country name as +selected+ to
+ end
+
+ # Returns a string of option tags for pretty much any country in the world. Supply a country name as +selected+ to
# have it marked as the selected option tag. You can also supply an array of countries as +priority_countries+, so
# that they will be listed above the rest of the (long) list.
#
# NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag.
def country_options_for_select(selected = nil, priority_countries = nil)
country_options = ""
-
+
if priority_countries
country_options += options_for_select(priority_countries, selected)
country_options += "<option>-------------</option>\n"
@@ -264,23 +264,27 @@ module ActionView
include FormOptionsHelper
def to_select_tag(choices, options, html_options)
+ html_options = html_options.stringify_keys
add_default_name_and_id(html_options)
content_tag("select", add_blank_option(options_for_select(choices, value), options[:include_blank]), html_options)
end
def to_collection_select_tag(collection, value_method, text_method, options, html_options)
+ html_options = html_options.stringify_keys
add_default_name_and_id(html_options)
content_tag(
"select", add_blank_option(options_from_collection_for_select(collection, value_method, text_method, value), options[:include_blank]), html_options
)
end
-
+
def to_country_select_tag(priority_countries, options, html_options)
+ html_options = html_options.stringify_keys
add_default_name_and_id(html_options)
content_tag("select", add_blank_option(country_options_for_select(value, priority_countries), options[:include_blank]), html_options)
end
def to_time_zone_select_tag(priority_zones, options, html_options)
+ html_options = html_options.stringify_keys
add_default_name_and_id(html_options)
content_tag("select",
add_blank_option(
diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb
index a5b18fe7f0..60e3bbb67b 100644
--- a/actionpack/lib/action_view/helpers/form_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb
@@ -6,21 +6,20 @@ module ActionView
# Provides a number of methods for creating form tags that doesn't rely on conventions with an object assigned to the template like
# FormHelper does. With the FormTagHelper, you provide the names and values yourself.
module FormTagHelper
- # Starts a form tag that points the action to an url configured with <tt>url_for_options</tt> just like
+ # Starts a form tag that points the action to an url configured with <tt>url_for_options</tt> just like
# ActionController::Base#url_for. The method for the form defaults to POST.
#
# Options:
# * <tt>:multipart</tt> - If set to true, the enctype is set to "multipart/form-data".
def form_tag(url_for_options = {}, options = {}, *parameters_for_url)
- html_options = { "method" => "post" }.merge(options)
-
+ html_options = { "method" => "post" }.merge(options.stringify_keys)
+
if html_options[:multipart]
html_options["enctype"] = "multipart/form-data"
html_options.delete(:multipart)
end
-
+
html_options["action"] = url_for(url_for_options, *parameters_for_url)
-
tag("form", html_options, true)
end
@@ -32,48 +31,49 @@ module ActionView
end
def select_tag(name, option_tags = nil, options = {})
- content_tag("select", option_tags, { "name" => name, "id" => name }.update(options))
+ content_tag("select", option_tags, { "name" => name, "id" => name }.update(options.stringify_keys))
end
def text_field_tag(name, value = nil, options = {})
- tag("input", {"type" => "text", "name" => name, "id" => name, "value" => value}.update(options))
+ tag("input", { "type" => "text", "name" => name, "id" => name, "value" => value }.update(options.stringify_keys))
end
def hidden_field_tag(name, value = nil, options = {})
- text_field_tag(name, value, options.update("type" => "hidden"))
+ text_field_tag(name, value, options.stringify_keys.update("type" => "hidden"))
end
def file_field_tag(name, options = {})
- text_field_tag(name, nil, options.update("type" => "file"))
+ text_field_tag(name, nil, options.stringify_keys.update("type" => "file"))
end
def password_field_tag(name = "password", value = nil, options = {})
- text_field_tag(name, value, options.update("type" => "password"))
+ text_field_tag(name, value, options.stringify_keys.update("type" => "password"))
end
def text_area_tag(name, content = nil, options = {})
- if options[:size]
- options["cols"], options["rows"] = options[:size].split("x")
- options.delete(:size)
+ options = options.stringify_keys
+ if options["size"]
+ options["cols"], options["rows"] = options["size"].split("x")
+ options.delete("size")
end
-
- content_tag("textarea", content, { "name" => name, "id" => name }.update(options))
+
+ content_tag("textarea", content, { "name" => name, "id" => name }.update(options.stringify_keys))
end
def check_box_tag(name, value = "1", checked = false, options = {})
- html_options = {"type" => "checkbox", "name" => name, "id" => name, "value" => value}.update(options)
+ html_options = { "type" => "checkbox", "name" => name, "id" => name, "value" => value }.update(options.stringify_keys)
html_options["checked"] = "checked" if checked
tag("input", html_options)
end
def radio_button_tag(name, value, checked = false, options = {})
- html_options = {"type" => "radio", "name" => name, "id" => name, "value" => value}.update(options)
+ html_options = { "type" => "radio", "name" => name, "id" => name, "value" => value }.update(options.stringify_keys)
html_options["checked"] = "checked" if checked
tag("input", html_options)
end
def submit_tag(value = "Save changes", options = {})
- tag("input", {"type" => "submit", "name" => "submit", "value" => value}.update(options))
+ tag("input", { "type" => "submit", "name" => "submit", "value" => value }.update(options.stringify_keys))
end
end
end
diff --git a/actionpack/lib/action_view/helpers/tag_helper.rb b/actionpack/lib/action_view/helpers/tag_helper.rb
index 5ebfecb8bd..fa74e3f4ee 100644
--- a/actionpack/lib/action_view/helpers/tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/tag_helper.rb
@@ -7,14 +7,14 @@ module ActionView
module TagHelper
include ERB::Util
- # Examples:
+ # Examples:
# * <tt>tag("br") => <br /></tt>
# * <tt>tag("input", { "type" => "text"}) => <input type="text" /></tt>
def tag(name, options = {}, open = false)
"<#{name}#{tag_options(options)}" + (open ? ">" : " />")
end
-
- # Examples:
+
+ # Examples:
# * <tt>content_tag("p", "Hello world!") => <p>Hello world!</p></tt>
# * <tt>content_tag("div", content_tag("p", "Hello world!"), "class" => "strong") => </tt>
# <tt><div class="strong"><p>Hello world!</p></div></tt>
@@ -26,7 +26,7 @@ module ActionView
def tag_options(options)
unless options.empty?
" " + options.map { |key, value|
- %(#{key}="#{html_escape(value)}")
+ %(#{key}="#{html_escape(value.to_s)}")
}.sort.join(" ")
end
end
diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb
index 26a8b74faa..1c67e3efb4 100644
--- a/actionpack/lib/action_view/helpers/text_helper.rb
+++ b/actionpack/lib/action_view/helpers/text_helper.rb
@@ -1,7 +1,7 @@
module ActionView
module Helpers #:nodoc:
# Provides a set of methods for working with text strings that can help unburden the level of inline Ruby code in the
- # templates. In the example below we iterate over a collection of posts provided to the template and prints each title
+ # templates. In the example below we iterate over a collection of posts provided to the template and prints each title
# after making sure it doesn't run longer than 20 characters:
# <% for post in @posts %>
# Title: <%= truncate(post.title, 20) %>
@@ -29,14 +29,14 @@ module ActionView
if text.nil? || phrase.nil? then return end
text.gsub(/(#{escape_regexp(phrase)})/i, highlighter) unless text.nil?
end
-
+
# Extracts an excerpt from the +text+ surrounding the +phrase+ with a number of characters on each side determined
- # by +radius+. If the phrase isn't found, nil is returned. Ex:
+ # by +radius+. If the phrase isn't found, nil is returned. Ex:
# excerpt("hello my world", "my", 3) => "...lo my wo..."
def excerpt(text, phrase, radius = 100, excerpt_string = "...")
if text.nil? || phrase.nil? then return end
phrase = escape_regexp(phrase)
-
+
if found_pos = text =~ /(#{phrase})/i
start_pos = [ found_pos - radius, 0 ].max
end_pos = [ found_pos + phrase.length + radius, text.length ].min
@@ -58,7 +58,7 @@ module ActionView
plural
elsif Object.const_defined?("Inflector")
Inflector.pluralize(singular)
- else
+ else
singular + "s"
end
end
@@ -66,13 +66,13 @@ module ActionView
begin
require "redcloth"
- # Returns the text with all the Textile codes turned into HTML-tags.
+ # Returns the text with all the Textile codes turned into HTML-tags.
# <i>This method is only available if RedCloth can be required</i>.
def textilize(text)
text.empty? ? "" : RedCloth.new(text, [ :hard_breaks ]).to_html
end
- # Returns the text with all the Textile codes turned into HTML-tags, but without the regular bounding <p> tag.
+ # Returns the text with all the Textile codes turned into HTML-tags, but without the regular bounding <p> tag.
# <i>This method is only available if RedCloth can be required</i>.
def textilize_without_paragraph(text)
textiled = textilize(text)
@@ -87,7 +87,7 @@ module ActionView
begin
require "bluecloth"
- # Returns the text with all the Markdown codes turned into HTML-tags.
+ # Returns the text with all the Markdown codes turned into HTML-tags.
# <i>This method is only available if BlueCloth can be required</i>.
def markdown(text)
text.empty? ? "" : BlueCloth.new(text).to_html
@@ -101,7 +101,7 @@ module ActionView
#
# Example:
# auto_link("Go to http://www.rubyonrails.com and say hello to david@loudthinking.com") =>
- # Go to <a href="http://www.rubyonrails.com">http://www.rubyonrails.com</a> and
+ # Go to <a href="http://www.rubyonrails.com">http://www.rubyonrails.com</a> and
# say hello to <a href="mailto:david@loudthinking.com">david@loudthinking.com</a>
def auto_link(text, link = :all)
case link
@@ -115,7 +115,7 @@ module ActionView
def strip_links(text)
text.gsub(/<a.*>(.*)<\/a>/m, '\1')
end
-
+
private
# Returns a version of the text that's safe to use in a regular expression without triggering engine features.
def escape_regexp(text)
@@ -133,4 +133,4 @@ module ActionView
end
end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb
index 951760b3ba..901374d877 100644
--- a/actionpack/lib/action_view/helpers/url_helper.rb
+++ b/actionpack/lib/action_view/helpers/url_helper.rb
@@ -7,26 +7,27 @@ module ActionView
module UrlHelper
# Returns the URL for the set of +options+ provided. See the valid options in link:classes/ActionController/Base.html#M000021
def url_for(options = {}, *parameters_for_method_reference)
- if Hash === options then options = { :only_path => true }.merge(options) end
+ if Hash === options then options = { :only_path => true }.update(options.stringify_keys) end
@controller.send(:url_for, options, *parameters_for_method_reference)
end
# Creates a link tag of the given +name+ using an URL created by the set of +options+. See the valid options in
# link:classes/ActionController/Base.html#M000021. It's also possible to pass a string instead of an options hash to
- # get a link tag that just points without consideration. If nil is passed as a name, the link itself will become the name.
- # The html_options have a special feature for creating javascript confirm alerts where if you pass :confirm => 'Are you sure?',
+ # get a link tag that just points without consideration. If nil is passed as a name, the link itself will become the name.
+ # The html_options have a special feature for creating javascript confirm alerts where if you pass :confirm => 'Are you sure?',
# the link will be guarded with a JS popup asking that question. If the user accepts, the link is processed, otherwise not.
#
# Example:
# link_to "Delete this page", { :action => "destroy", :id => @page.id }, :confirm => "Are you sure?"
- def link_to(name, options = {}, html_options = {}, *parameters_for_method_reference)
- convert_confirm_option_to_javascript!(html_options) unless html_options.nil?
+ def link_to(name, options = {}, html_options = nil, *parameters_for_method_reference)
+ html_options = (html_options || {}).stringify_keys
+ convert_confirm_option_to_javascript!(html_options)
if options.is_a?(String)
- content_tag "a", name || options, (html_options || {}).merge({ "href" => options })
+ content_tag "a", name || options, (html_options || {}).merge("href" => options)
else
content_tag(
- "a", name || url_for(options, *parameters_for_method_reference),
- (html_options || {}).merge({ "href" => url_for(options, *parameters_for_method_reference) })
+ "a", name || url_for(options, *parameters_for_method_reference),
+ (html_options || {}).merge("href" => url_for(options, *parameters_for_method_reference))
)
end
end
@@ -41,7 +42,7 @@ module ActionView
# * <tt>:border</tt> - Is set to 0 by default
# * <tt>:align</tt> - Sets the alignment, no special features
#
- # The +src+ can be supplied as a...
+ # The +src+ can be supplied as a...
# * full path, like "/my_images/image.gif"
# * file name, like "rss.gif", that gets expanded to "/images/rss.gif"
# * file name without extension, like "logo", that gets expanded to "/images/logo.png"
@@ -51,8 +52,9 @@ module ActionView
# link_image_to "delete", { :action => "destroy" }, :size => "10x10", :confirm => "Are you sure?", "class" => "admin"
def link_image_to(src, options = {}, html_options = {}, *parameters_for_method_reference)
image_options = { "src" => src.include?("/") ? src : "/images/#{src}" }
- image_options["src"] = image_options["src"] + ".png" unless image_options["src"].include?(".")
-
+ image_options["src"] += ".png" unless image_options["src"].include?(".")
+
+ html_options = html_options.stringify_keys
if html_options["alt"]
image_options["alt"] = html_options["alt"]
html_options.delete "alt"
@@ -71,7 +73,7 @@ module ActionView
else
image_options["border"] = "0"
end
-
+
if html_options["align"]
image_options["align"] = html_options["align"]
html_options.delete "align"
@@ -82,9 +84,9 @@ module ActionView
alias_method :link_to_image, :link_image_to # deprecated name
- # Creates a link tag of the given +name+ using an URL created by the set of +options+, unless the current
+ # Creates a link tag of the given +name+ using an URL created by the set of +options+, unless the current
# request uri is the same as the link's, in which case only the name is returned (or the
- # given block is yielded, if one exists). This is useful for creating link bars where you don't want to link
+ # given block is yielded, if one exists). This is useful for creating link bars where you don't want to link
# to the page currently being viewed.
def link_to_unless_current(name, options = {}, html_options = {}, *parameters_for_method_reference)
if current_page?(options)
@@ -107,8 +109,8 @@ module ActionView
# mail_to "me@domain.com", "My email", :encode => "hex" # =>
# <a href="mailto:%6d%65@%64%6f%6d%61%69%6e.%63%6f%6d">My email</a>
def mail_to(email_address, name = nil, html_options = {})
- encode = html_options[:encode]
- html_options.delete(:encode)
+ html_options = html_options.stringify_keys
+ encode = html_options.delete("encode")
string = ''
if encode == 'javascript'
tmp = "document.write('#{content_tag("a", name || email_address, html_options.merge({ "href" => "mailto:"+email_address.to_s }))}');"
@@ -137,9 +139,8 @@ module ActionView
private
def convert_confirm_option_to_javascript!(html_options)
- if html_options.include?(:confirm)
- html_options["onclick"] = "return confirm('#{html_options[:confirm]}');"
- html_options.delete(:confirm)
+ if confirm = html_options.delete("confirm")
+ html_options["onclick"] = "return confirm('#{confirm}');"
end
end
end
diff --git a/actionpack/test/template/active_record_helper_test.rb b/actionpack/test/template/active_record_helper_test.rb
index e650b4f0b8..67001082b8 100644
--- a/actionpack/test/template/active_record_helper_test.rb
+++ b/actionpack/test/template/active_record_helper_test.rb
@@ -48,7 +48,7 @@ class ActiveRecordHelperTest < Test::Unit::TestCase
@controller = Class.new do
def url_for(options, *parameters_for_method_reference)
- options[:action]
+ options[:action] || options["action"]
end
end
@controller = @controller.new
diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb
index 6b1deb575e..7f7f473564 100644
--- a/actionpack/test/template/form_helper_test.rb
+++ b/actionpack/test/template/form_helper_test.rb
@@ -15,7 +15,7 @@ class FormHelperTest < Test::Unit::TestCase
$VERBOSE = old_verbose
def setup
- @post = Post.new
+ @post = Post.new
def @post.errors() Class.new{ def on(field) field == "author_name" end }.new end
def @post.id; 123; end
@@ -47,31 +47,29 @@ class FormHelperTest < Test::Unit::TestCase
end
def test_text_field_with_options
- assert_equal(
- '<input id="post_title" name="post[title]" size="35" type="text" value="Hello World" />',
- text_field("post", "title", "size" => "35")
- )
+ expected = '<input id="post_title" name="post[title]" size="35" type="text" value="Hello World" />'
+ assert_equal expected, text_field("post", "title", "size" => 35)
+ assert_equal expected, text_field("post", "title", :size => 35)
end
-
+
def test_text_field_assuming_size
- assert_equal(
- '<input id="post_title" maxlength="35" name="post[title]" size="35" type="text" value="Hello World" />',
- text_field("post", "title", "maxlength" => 35)
- )
+ expected = '<input id="post_title" maxlength="35" name="post[title]" size="35" type="text" value="Hello World" />'
+ assert_equal expected, text_field("post", "title", "maxlength" => 35)
+ assert_equal expected, text_field("post", "title", :maxlength => 35)
end
-
+
def test_check_box
assert_equal(
'<input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
check_box("post", "secret")
)
-
+
@post.secret = 0
assert_equal(
'<input id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
- check_box("post", "secret")
+ check_box("post", "secret")
)
-
+
@post.secret = true
assert_equal(
'<input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
@@ -81,20 +79,20 @@ class FormHelperTest < Test::Unit::TestCase
def test_radio_button
assert_equal('<input checked="checked" id="post_title" name="post[title]" size="30" type="radio" value="Hello World" />',
- radio_button("post", "title", "Hello World")
+ radio_button("post", "title", "Hello World")
)
assert_equal('<input id="post_title" name="post[title]" size="30" type="radio" value="Goodbye World" />',
- radio_button("post", "title", "Goodbye World")
+ radio_button("post", "title", "Goodbye World")
)
end
-
+
def test_text_area
assert_equal(
'<textarea cols="40" id="post_body" name="post[body]" rows="20" wrap="virtual">Back to the hill and over it again!</textarea>',
text_area("post", "body")
)
end
-
+
def test_text_area_with_escapes
@post.body = "Back to <i>the</i> hill and over it again!"
assert_equal(
@@ -109,12 +107,11 @@ class FormHelperTest < Test::Unit::TestCase
text_area("post", "body")
)
end
-
-
+
def test_explicit_name
assert_equal(
'<input id="post_title" name="dont guess" size="30" type="text" value="Hello World" />', text_field("post", "title", "name" => "dont guess")
- )
+ )
assert_equal(
'<textarea cols="40" id="post_body" name="really!" rows="20" wrap="virtual">Back to the hill and over it again!</textarea>',
text_area("post", "body", "name" => "really!")
@@ -123,12 +120,18 @@ class FormHelperTest < Test::Unit::TestCase
'<input checked="checked" id="post_secret" name="i mean it" type="checkbox" value="1" /><input name="i mean it" type="hidden" value="0" />',
check_box("post", "secret", "name" => "i mean it")
)
+ assert_equal text_field("post", "title", "name" => "dont guess"),
+ text_field("post", "title", :name => "dont guess")
+ assert_equal text_area("post", "body", "name" => "really!"),
+ text_area("post", "body", :name => "really!")
+ assert_equal check_box("post", "secret", "name" => "i mean it"),
+ check_box("post", "secret", :name => "i mean it")
end
-
+
def test_explicit_id
assert_equal(
'<input id="dont guess" name="post[title]" size="30" type="text" value="Hello World" />', text_field("post", "title", "id" => "dont guess")
- )
+ )
assert_equal(
'<textarea cols="40" id="really!" name="post[body]" rows="20" wrap="virtual">Back to the hill and over it again!</textarea>',
text_area("post", "body", "id" => "really!")
@@ -137,6 +140,12 @@ class FormHelperTest < Test::Unit::TestCase
'<input checked="checked" id="i mean it" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
check_box("post", "secret", "id" => "i mean it")
)
+ assert_equal text_field("post", "title", "id" => "dont guess"),
+ text_field("post", "title", :id => "dont guess")
+ assert_equal text_area("post", "body", "id" => "really!"),
+ text_area("post", "body", :id => "really!")
+ assert_equal check_box("post", "secret", "id" => "i mean it"),
+ check_box("post", "secret", :id => "i mean it")
end
def test_auto_index
@@ -159,7 +168,5 @@ class FormHelperTest < Test::Unit::TestCase
assert_equal("<input id=\"post_#{pid}_title\" name=\"post[#{pid}][title]\" size=\"30\" type=\"radio\" value=\"Goodbye World\" />",
radio_button("post[]", "title", "Goodbye World")
)
-
end
-
end
diff --git a/actionpack/test/template/form_options_helper_test.rb b/actionpack/test/template/form_options_helper_test.rb
index 4203ab7079..a94f81a728 100644
--- a/actionpack/test/template/form_options_helper_test.rb
+++ b/actionpack/test/template/form_options_helper_test.rb
@@ -46,7 +46,7 @@ class FormOptionsHelperTest < Test::Unit::TestCase
)
end
-
+
def test_collection_options_with_preselected_value
@posts = [
Post.new("<Abe> went home", "<Abe>", "To a little house", "shh!"),
@@ -75,14 +75,14 @@ class FormOptionsHelperTest < Test::Unit::TestCase
def test_array_options_for_select
assert_equal(
- "<option>&lt;Denmark&gt;</option>\n<option>USA</option>\n<option>Sweden</option>",
+ "<option>&lt;Denmark&gt;</option>\n<option>USA</option>\n<option>Sweden</option>",
options_for_select([ "<Denmark>", "USA", "Sweden" ])
)
end
def test_array_options_for_select_with_selection
assert_equal(
- "<option>Denmark</option>\n<option selected=\"selected\">&lt;USA&gt;</option>\n<option>Sweden</option>",
+ "<option>Denmark</option>\n<option selected=\"selected\">&lt;USA&gt;</option>\n<option>Sweden</option>",
options_for_select([ "Denmark", "<USA>", "Sweden" ], "<USA>")
)
end
@@ -96,21 +96,21 @@ class FormOptionsHelperTest < Test::Unit::TestCase
def test_hash_options_for_select
assert_equal(
- "<option value=\"&lt;Kroner&gt;\">&lt;DKR&gt;</option>\n<option value=\"Dollar\">$</option>",
+ "<option value=\"&lt;Kroner&gt;\">&lt;DKR&gt;</option>\n<option value=\"Dollar\">$</option>",
options_for_select({ "$" => "Dollar", "<DKR>" => "<Kroner>" })
)
end
def test_hash_options_for_select_with_selection
assert_equal(
- "<option value=\"&lt;Kroner&gt;\">&lt;DKR&gt;</option>\n<option value=\"Dollar\" selected=\"selected\">$</option>",
+ "<option value=\"&lt;Kroner&gt;\">&lt;DKR&gt;</option>\n<option value=\"Dollar\" selected=\"selected\">$</option>",
options_for_select({ "$" => "Dollar", "<DKR>" => "<Kroner>" }, "Dollar")
)
end
def test_hash_options_for_select_with_selection
assert_equal(
- "<option value=\"&lt;Kroner&gt;\" selected=\"selected\">&lt;DKR&gt;</option>\n<option value=\"Dollar\" selected=\"selected\">$</option>",
+ "<option value=\"&lt;Kroner&gt;\" selected=\"selected\">&lt;DKR&gt;</option>\n<option value=\"Dollar\" selected=\"selected\">$</option>",
options_for_select({ "$" => "Dollar", "<DKR>" => "<Kroner>" }, [ "Dollar", "<Kroner>" ])
)
end
@@ -197,7 +197,7 @@ class FormOptionsHelperTest < Test::Unit::TestCase
@post = Post.new
@post.category = "<mus>"
assert_equal(
- "<select id=\"post_category\" name=\"post[category]\"><option>abe</option>\n<option selected=\"selected\">&lt;mus&gt;</option>\n<option>hest</option></select>",
+ "<select id=\"post_category\" name=\"post[category]\"><option>abe</option>\n<option selected=\"selected\">&lt;mus&gt;</option>\n<option>hest</option></select>",
select("post", "category", %w( abe <mus> hest))
)
end
@@ -206,7 +206,7 @@ class FormOptionsHelperTest < Test::Unit::TestCase
@post = Post.new
@post.category = "<mus>"
assert_equal(
- "<select id=\"post_category\" name=\"post[category]\"><option></option>\n<option>abe</option>\n<option selected=\"selected\">&lt;mus&gt;</option>\n<option>hest</option></select>",
+ "<select id=\"post_category\" name=\"post[category]\"><option></option>\n<option>abe</option>\n<option selected=\"selected\">&lt;mus&gt;</option>\n<option>hest</option></select>",
select("post", "category", %w( abe <mus> hest), :include_blank => true)
)
end
@@ -222,7 +222,7 @@ class FormOptionsHelperTest < Test::Unit::TestCase
@post.author_name = "Babe"
assert_equal(
- "<select id=\"post_author_name\" name=\"post[author_name]\"><option value=\"&lt;Abe&gt;\">&lt;Abe&gt;</option>\n<option value=\"Babe\" selected=\"selected\">Babe</option>\n<option value=\"Cabe\">Cabe</option></select>",
+ "<select id=\"post_author_name\" name=\"post[author_name]\"><option value=\"&lt;Abe&gt;\">&lt;Abe&gt;</option>\n<option value=\"Babe\" selected=\"selected\">Babe</option>\n<option value=\"Cabe\">Cabe</option></select>",
collection_select("post", "author_name", @posts, "author_name", "author_name")
)
end
@@ -238,7 +238,7 @@ class FormOptionsHelperTest < Test::Unit::TestCase
@post.author_name = "Babe"
assert_equal(
- "<select id=\"post_author_name\" name=\"post[author_name]\" style=\"width: 200px\"><option></option>\n<option value=\"&lt;Abe&gt;\">&lt;Abe&gt;</option>\n<option value=\"Babe\" selected=\"selected\">Babe</option>\n<option value=\"Cabe\">Cabe</option></select>",
+ "<select id=\"post_author_name\" name=\"post[author_name]\" style=\"width: 200px\"><option></option>\n<option value=\"&lt;Abe&gt;\">&lt;Abe&gt;</option>\n<option value=\"Babe\" selected=\"selected\">Babe</option>\n<option value=\"Cabe\">Cabe</option></select>",
collection_select("post", "author_name", @posts, "author_name", "author_name", { :include_blank => true }, "style" => "width: 200px")
)
end
@@ -291,6 +291,8 @@ class FormOptionsHelperTest < Test::Unit::TestCase
"<option value=\"E\">E</option>" +
"</select>",
html
+ assert_equal html, time_zone_select("firm", "time_zone", nil, {},
+ :style => "color: red")
end
def test_time_zone_select_with_blank_and_style
@@ -306,6 +308,8 @@ class FormOptionsHelperTest < Test::Unit::TestCase
"<option value=\"E\">E</option>" +
"</select>",
html
+ assert_equal html, time_zone_select("firm", "time_zone", nil,
+ { :include_blank => true }, :style => "color: red")
end
def test_time_zone_select_with_priority_zones
diff --git a/actionpack/test/template/form_tag_helper_test.rb b/actionpack/test/template/form_tag_helper_test.rb
index 6036dd4b50..8fd6300b82 100644
--- a/actionpack/test/template/form_tag_helper_test.rb
+++ b/actionpack/test/template/form_tag_helper_test.rb
@@ -11,12 +11,13 @@ class FormTagHelperTest < Test::Unit::TestCase
%(hidden_field_tag "id", 3) => %(<input id="id" name="id" type="hidden" value="3" />),
%(password_field_tag) => %(<input id="password" name="password" type="password" value="" />),
%(text_area_tag("body", "hello world", :size => "20x40")) => %(<textarea cols="20" id="body" name="body" rows="40">hello world</textarea>),
+ %(text_area_tag("body", "hello world", "size" => "20x40")) => %(<textarea cols="20" id="body" name="body" rows="40">hello world</textarea>),
%(check_box_tag("admin")) => %(<input id="admin" name="admin" type="checkbox" value="1" />),
%(radio_button_tag("people", "david")) => %(<input id="people" name="people" type="radio" value="david" />),
%(select_tag("people", "<option>david</option>")) => %(<select id="people" name="people"><option>david</option></select>),
}
def test_tags
- MethodToTag.each { |method, tag| assert_equal(eval(method), tag) }
+ MethodToTag.each { |method, tag| assert_equal(tag, eval(method)) }
end
-end \ No newline at end of file
+end
diff --git a/actionpack/test/template/tag_helper_test.rb b/actionpack/test/template/tag_helper_test.rb
index 2db1bac238..9d8d2644e8 100644
--- a/actionpack/test/template/tag_helper_test.rb
+++ b/actionpack/test/template/tag_helper_test.rb
@@ -8,23 +8,26 @@ class TagHelperTest < Test::Unit::TestCase
def test_tag
assert_equal "<p class=\"show\" />", tag("p", "class" => "show")
+ assert_equal tag("p", "class" => "show"), tag("p", :class => "show")
end
-
+
def test_content_tag
assert_equal "<a href=\"create\">Create</a>", content_tag("a", "Create", "href" => "create")
+ assert_equal content_tag("a", "Create", "href" => "create"),
+ content_tag("a", "Create", :href => "create")
end
def test_mail_to_with_javascript
- assert_equal "<script type=\"text/javascript\" language=\"javascript\">eval(unescape('%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%61%20%68%72%65%66%3d%22%6d%61%69%6c%74%6f%3a%6d%65%40%64%6f%6d%61%69%6e%2e%63%6f%6d%22%3e%4d%79%20%65%6d%61%69%6c%3c%2f%61%3e%27%29%3b'))</script>", mail_to("me@domain.com", "My email", :encode => "javascript")
+ assert_equal "<script type=\"text/javascript\" language=\"javascript\">eval(unescape('%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%61%20%68%72%65%66%3d%22%6d%61%69%6c%74%6f%3a%6d%65%40%64%6f%6d%61%69%6e%2e%63%6f%6d%22%3e%4d%79%20%65%6d%61%69%6c%3c%2f%61%3e%27%29%3b'))</script>", mail_to("me@domain.com", "My email", :encode => "javascript")
end
def test_mail_to_with_hex
- assert_equal "<a href=\"mailto:%6d%65@%64%6f%6d%61%69%6e.%63%6f%6d\">My email</a>", mail_to("me@domain.com", "My email", :encode => "hex")
+ assert_equal "<a href=\"mailto:%6d%65@%64%6f%6d%61%69%6e.%63%6f%6d\">My email</a>", mail_to("me@domain.com", "My email", :encode => "hex")
end
def test_mail_to
- assert_equal "<a href=\"mailto:me@domain.com\">My email</a>", mail_to("me@domain.com", "My email")
+ assert_equal "<a href=\"mailto:me@domain.com\">My email</a>", mail_to("me@domain.com", "My email")
end
# FIXME: Test form tag
-end \ No newline at end of file
+end
diff --git a/actionpack/test/template/text_helper_test.rb b/actionpack/test/template/text_helper_test.rb
index 2082f4aae8..aba0d99699 100644
--- a/actionpack/test/template/text_helper_test.rb
+++ b/actionpack/test/template/text_helper_test.rb
@@ -8,11 +8,11 @@ class TextHelperTest < Test::Unit::TestCase
assert_equal "Hello World!", truncate("Hello World!", 12)
assert_equal "Hello Worl...", truncate("Hello World!!", 12)
end
-
+
def test_strip_links
assert_equal "on my mind", strip_links("<a href='almost'>on my mind</a>")
end
-
+
def test_highlighter
assert_equal(
"This is a <strong class=\"highlight\">beautiful</strong> morning",
@@ -29,7 +29,7 @@ class TextHelperTest < Test::Unit::TestCase
highlight("This is a beautiful morning, but also a beautiful day", "beautiful", '<b>\1</b>')
)
end
-
+
def test_highlighter_with_regexp
assert_equal(
"This is a <strong class=\"highlight\">beautiful!</strong> morning",
@@ -46,7 +46,7 @@ class TextHelperTest < Test::Unit::TestCase
highlight("This is a beautiful? morning", "beautiful? morning")
)
end
-
+
def test_excerpt
assert_equal("...is a beautiful morni...", excerpt("This is a beautiful morning", "beautiful", 5))
assert_equal("This is a...", excerpt("This is a beautiful morning", "this", 5))
@@ -54,16 +54,16 @@ class TextHelperTest < Test::Unit::TestCase
assert_equal("...iful morning", excerpt("This is a beautiful morning", "morning", 5))
assert_nil excerpt("This is a beautiful morning", "day")
end
-
+
def test_pluralization
assert_equal("1 count", pluralize(1, "count"))
assert_equal("2 counts", pluralize(2, "count"))
end
-
+
def test_auto_linking
assert_equal %(hello <a href="mailto:david@loudthinking.com">david@loudthinking.com</a>), auto_link("hello david@loudthinking.com", :email_addresses)
assert_equal %(Go to <a href="http://www.rubyonrails.com">http://www.rubyonrails.com</a>), auto_link("Go to http://www.rubyonrails.com", :urls)
assert_equal %(Go to http://www.rubyonrails.com), auto_link("Go to http://www.rubyonrails.com", :email_addresses)
assert_equal %(Go to <a href="http://www.rubyonrails.com">http://www.rubyonrails.com</a> and say hello to <a href="mailto:david@loudthinking.com">david@loudthinking.com</a>), auto_link("Go to http://www.rubyonrails.com and say hello to david@loudthinking.com")
end
-end \ No newline at end of file
+end
diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb
index 6e94d98ebe..379db0b9b7 100644
--- a/actionpack/test/template/url_helper_test.rb
+++ b/actionpack/test/template/url_helper_test.rb
@@ -21,26 +21,31 @@ class UrlHelperTest < Test::Unit::TestCase
def test_link_tag_with_straight_url
assert_equal "<a href=\"http://www.world.com\">Hello</a>", link_to("Hello", "http://www.world.com")
end
-
+
def test_link_tag_with_javascript_confirm
assert_equal(
- "<a href=\"http://www.world.com\" onclick=\"return confirm('Are you sure?');\">Hello</a>",
+ "<a href=\"http://www.world.com\" onclick=\"return confirm('Are you sure?');\">Hello</a>",
link_to("Hello", "http://www.world.com", :confirm => "Are you sure?")
)
end
-
+
def test_link_to_image
assert_equal(
- "<a href=\"http://www.world.com\"><img alt=\"Rss\" border=\"0\" height=\"45\" src=\"/images/rss.png\" width=\"30\" /></a>",
+ "<a href=\"http://www.world.com\"><img alt=\"Rss\" border=\"0\" height=\"45\" src=\"/images/rss.png\" width=\"30\" /></a>",
link_to_image("rss", "http://www.world.com", "size" => "30x45")
)
assert_equal(
- "<a class=\"admin\" href=\"http://www.world.com\"><img alt=\"Feed\" border=\"0\" height=\"45\" src=\"/images/rss.gif\" width=\"30\" /></a>",
+ "<a class=\"admin\" href=\"http://www.world.com\"><img alt=\"Feed\" border=\"0\" height=\"45\" src=\"/images/rss.gif\" width=\"30\" /></a>",
link_to_image("rss.gif", "http://www.world.com", "size" => "30x45", "alt" => "Feed", "class" => "admin")
)
+
+ assert_equal link_to_image("rss", "http://www.world.com", "size" => "30x45"),
+ link_to_image("rss", "http://www.world.com", :size => "30x45")
+ assert_equal link_to_image("rss.gif", "http://www.world.com", "size" => "30x45", "alt" => "Feed", "class" => "admin"),
+ link_to_image("rss.gif", "http://www.world.com", :size => "30x45", :alt => "Feed", :class => "admin")
end
-
+
def test_link_unless_current
@request = RequestMock.new("http://www.world.com")
assert_equal "Showing", link_to_unless_current("Showing", :action => "show", :controller => "weblog")
@@ -55,11 +60,13 @@ class UrlHelperTest < Test::Unit::TestCase
assert_equal "<a href=\"mailto:david@loudthinking.com\">david@loudthinking.com</a>", mail_to("david@loudthinking.com")
assert_equal "<a href=\"mailto:david@loudthinking.com\">David Heinemeier Hansson</a>", mail_to("david@loudthinking.com", "David Heinemeier Hansson")
assert_equal(
- "<a class=\"admin\" href=\"mailto:david@loudthinking.com\">David Heinemeier Hansson</a>",
+ "<a class=\"admin\" href=\"mailto:david@loudthinking.com\">David Heinemeier Hansson</a>",
mail_to("david@loudthinking.com", "David Heinemeier Hansson", "class" => "admin")
)
+ assert_equal mail_to("david@loudthinking.com", "David Heinemeier Hansson", "class" => "admin"),
+ mail_to("david@loudthinking.com", "David Heinemeier Hansson", :class => "admin")
end
-
+
def test_link_with_nil_html_options
assert_equal "<a href=\"http://www.world.com\">Hello</a>", link_to("Hello", {:action => 'myaction'}, nil)
end