aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/CHANGELOG9
-rw-r--r--actionpack/lib/abstract_controller/rendering.rb17
-rw-r--r--actionpack/lib/action_controller/base.rb90
-rw-r--r--actionpack/lib/action_controller/deprecated/base.rb16
-rw-r--r--actionpack/lib/action_controller/metal/cookies.rb3
-rw-r--r--actionpack/lib/action_controller/metal/http_authentication.rb17
-rw-r--r--actionpack/lib/action_controller/railtie.rb1
-rw-r--r--actionpack/lib/action_dispatch/middleware/cookies.rb36
-rw-r--r--actionpack/lib/action_dispatch/middleware/session/cookie_store.rb2
-rw-r--r--actionpack/lib/action_dispatch/testing/integration.rb30
-rw-r--r--actionpack/lib/action_dispatch/testing/test_request.rb2
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb71
-rw-r--r--actionpack/lib/action_view/helpers/form_tag_helper.rb63
-rw-r--r--actionpack/test/abstract/abstract_controller_test.rb77
-rw-r--r--actionpack/test/abstract_unit.rb4
-rw-r--r--actionpack/test/controller/cookie_test.rb3
-rw-r--r--actionpack/test/controller/http_digest_authentication_test.rb5
-rw-r--r--actionpack/test/controller/integration_test.rb45
-rw-r--r--actionpack/test/template/erb/form_for_test.rb2
-rw-r--r--actionpack/test/template/form_helper_test.rb553
-rw-r--r--actionpack/test/template/form_tag_helper_test.rb30
21 files changed, 726 insertions, 350 deletions
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG
index c4ebedf1b0..84481d0194 100644
--- a/actionpack/CHANGELOG
+++ b/actionpack/CHANGELOG
@@ -1,17 +1,20 @@
*Rails 3.0.0 [Edge] (pending)*
+* Added all the new HTML5 form types as individual form tag methods (search, url, number, etc) #3646 [Stephen Celis]
+
* Changed the object used in routing constraints to be an instance of
- ActionDispatch::Request rather than Rack::Request
+ ActionDispatch::Request rather than Rack::Request [YK]
* Changed ActionDispatch::Request#method to return a String, to be compatible
with Rack::Request. Added ActionDispatch::Request#method_symbol to
- return a symbol form of the request method.
+ return a symbol form of the request method. [YK]
* Changed ActionDispatch::Request#method to return the original
method and #request_method to return the overridden method in the
case of methodoverride being used (this means that #method returns
"HEAD" and #request_method returns "GET" in HEAD requests). This
- is for compatibility with Rack::Request
+ is for compatibility with Rack::Request [YK]
+
*Rails 3.0.0 [beta 2] (April 1st, 2010)*
diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb
index b251bd6405..98c8c5fa67 100644
--- a/actionpack/lib/abstract_controller/rendering.rb
+++ b/actionpack/lib/abstract_controller/rendering.rb
@@ -89,9 +89,16 @@ module AbstractController
# Normalize arguments, options and then delegates render_to_body and
# sticks the result in self.response_body.
def render(*args, &block)
+ self.response_body = render_to_string(*args, &block)
+ end
+
+ # Raw rendering of a template to a string. Just convert the results of
+ # render_to_body into a String.
+ # :api: plugin
+ def render_to_string(*args, &block)
options = _normalize_args(*args, &block)
_normalize_options(options)
- self.response_body = render_to_body(options)
+ render_to_body(options)
end
# Raw rendering of a template to a Rack-compatible body.
@@ -101,14 +108,6 @@ module AbstractController
_render_template(options)
end
- # Raw rendering of a template to a string. Just convert the results of
- # render_to_body into a String.
- # :api: plugin
- def render_to_string(options={})
- _normalize_options(options)
- render_to_body(options)
- end
-
# Find and renders a template based on the options given.
# :api: private
def _render_template(options) #:nodoc:
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index 46a175d2fa..1dfc240029 100644
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -2,48 +2,59 @@ module ActionController
class Base < Metal
abstract!
- include AbstractController::Layouts
- include AbstractController::Translation
+ def self.without_modules(*modules)
+ modules = modules.map do |m|
+ m.is_a?(Symbol) ? ActionController.const_get(m) : m
+ end
- include ActionController::Helpers
-
- include ActionController::HideActions
- include ActionController::UrlFor
- include ActionController::Redirecting
- include ActionController::Rendering
- include ActionController::Renderers::All
- include ActionController::ConditionalGet
- include ActionController::RackDelegation
+ MODULES - modules
+ end
- # Legacy modules
- include SessionManagement
- include ActionController::Caching
- include ActionController::MimeResponds
- include ActionController::PolymorphicRoutes
+ MODULES = [
+ AbstractController::Layouts,
+ AbstractController::Translation,
- # Rails 2.x compatibility
- include ActionController::Compatibility
- include ActionController::ImplicitRender
+ Helpers,
+ HideActions,
+ UrlFor,
+ Redirecting,
+ Rendering,
+ Renderers::All,
+ ConditionalGet,
+ RackDelegation,
+ SessionManagement,
+ Caching,
+ MimeResponds,
+ PolymorphicRoutes,
+ ImplicitRender,
+
+ Cookies,
+ Flash,
+ Verification,
+ RequestForgeryProtection,
+ Streaming,
+ RecordIdentifier,
+ HttpAuthentication::Basic::ControllerMethods,
+ HttpAuthentication::Digest::ControllerMethods,
+
+ # Add instrumentations hooks at the bottom, to ensure they instrument
+ # all the methods properly.
+ Instrumentation,
- include ActionController::Cookies
- include ActionController::Flash
- include ActionController::Verification
- include ActionController::RequestForgeryProtection
- include ActionController::Streaming
- include ActionController::RecordIdentifier
- include ActionController::HttpAuthentication::Basic::ControllerMethods
- include ActionController::HttpAuthentication::Digest::ControllerMethods
+ # Before callbacks should also be executed the earliest as possible, so
+ # also include them at the bottom.
+ AbstractController::Callbacks,
- # Add instrumentations hooks at the bottom, to ensure they instrument
- # all the methods properly.
- include ActionController::Instrumentation
+ # The same with rescue, append it at the end to wrap as much as possible.
+ Rescue
+ ]
- # Before callbacks should also be executed the earliest as possible, so
- # also include them at the bottom.
- include AbstractController::Callbacks
+ MODULES.each do |mod|
+ include mod
+ end
- # The same with rescue, append it at the end to wrap as much as possible.
- include ActionController::Rescue
+ # Rails 2.x compatibility
+ include ActionController::Compatibility
def self.inherited(klass)
::ActionController::Base.subclasses << klass.to_s
@@ -55,15 +66,6 @@ module ActionController
@subclasses ||= []
end
- # This method has been moved to ActionDispatch::Request.filter_parameters
- def self.filter_parameter_logging(*args, &block)
- ActiveSupport::Deprecation.warn("Setting filter_parameter_logging in ActionController is deprecated and has no longer effect, please set 'config.filter_parameters' in config/application.rb instead", caller)
- filter = Rails.application.config.filter_parameters
- filter.concat(args)
- filter << block if block
- filter
- end
-
ActiveSupport.run_load_hooks(:action_controller, self)
end
end
diff --git a/actionpack/lib/action_controller/deprecated/base.rb b/actionpack/lib/action_controller/deprecated/base.rb
index 2fd60aacc7..05551ffee4 100644
--- a/actionpack/lib/action_controller/deprecated/base.rb
+++ b/actionpack/lib/action_controller/deprecated/base.rb
@@ -6,6 +6,15 @@ module ActionController
deprecated_config_writer(option, message)
end
+ # This method has been moved to ActionDispatch::Request.filter_parameters
+ def filter_parameter_logging(*args, &block)
+ ActiveSupport::Deprecation.warn("Setting filter_parameter_logging in ActionController is deprecated and has no longer effect, please set 'config.filter_parameters' in config/application.rb instead", caller)
+ filter = Rails.application.config.filter_parameters
+ filter.concat(args)
+ filter << block if block
+ filter
+ end
+
def deprecated_config_reader(option, message = nil)
message ||= "Reading #{option} directly from ActionController::Base is deprecated. " \
"Please read it from config.#{option}"
@@ -68,14 +77,11 @@ module ActionController
def cookie_verifier_secret=(value)
ActiveSupport::Deprecation.warn "ActionController::Base.cookie_verifier_secret= is deprecated. " <<
- "Please configure it on your application with config.cookie_secret=", caller
- ActionController::Base.config.secret = value
+ "Please configure it on your application with config.secret_token=", caller
end
def cookie_verifier_secret
- ActiveSupport::Deprecation.warn "ActionController::Base.cookie_verifier_secret is deprecated. " <<
- "Please use ActionController::Base.config.secret instead.", caller
- ActionController::Base.config.secret
+ ActiveSupport::Deprecation.warn "ActionController::Base.cookie_verifier_secret is deprecated.", caller
end
def trusted_proxies=(value)
diff --git a/actionpack/lib/action_controller/metal/cookies.rb b/actionpack/lib/action_controller/metal/cookies.rb
index 4aaa705203..d787f014cd 100644
--- a/actionpack/lib/action_controller/metal/cookies.rb
+++ b/actionpack/lib/action_controller/metal/cookies.rb
@@ -10,8 +10,7 @@ module ActionController #:nodoc:
private
def cookies
- raise "You must set config.cookie_secret in your app's config" if config.secret.blank?
- request.cookie_jar(:signing_secret => config.secret)
+ request.cookie_jar
end
end
end
diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb
index 424828f7e8..6bd6c15990 100644
--- a/actionpack/lib/action_controller/metal/http_authentication.rb
+++ b/actionpack/lib/action_controller/metal/http_authentication.rb
@@ -159,7 +159,7 @@ module ActionController
# Authenticate with HTTP Digest, returns true or false
def authenticate_with_http_digest(realm = "Application", &password_procedure)
- HttpAuthentication::Digest.authenticate(config.secret, request, realm, &password_procedure)
+ HttpAuthentication::Digest.authenticate(request, realm, &password_procedure)
end
# Render output including the HTTP Digest authentication header
@@ -169,14 +169,15 @@ module ActionController
end
# Returns false on a valid response, true otherwise
- def authenticate(secret_key, request, realm, &password_procedure)
- request.authorization && validate_digest_response(secret_key, request, realm, &password_procedure)
+ def authenticate(request, realm, &password_procedure)
+ request.authorization && validate_digest_response(request, realm, &password_procedure)
end
# Returns false unless the request credentials response value matches the expected value.
# First try the password as a ha1 digest password. If this fails, then try it as a plain
# text password.
- def validate_digest_response(secret_key, request, realm, &password_procedure)
+ def validate_digest_response(request, realm, &password_procedure)
+ secret_key = secret_token(request)
credentials = decode_credentials_header(request)
valid_nonce = validate_nonce(secret_key, request, credentials[:nonce])
@@ -225,7 +226,7 @@ module ActionController
end
def authentication_header(controller, realm)
- secret_key = controller.config.secret
+ secret_key = secret_token(controller.request)
nonce = self.nonce(secret_key)
opaque = opaque(secret_key)
controller.headers["WWW-Authenticate"] = %(Digest realm="#{realm}", qop="auth", algorithm=MD5, nonce="#{nonce}", opaque="#{opaque}")
@@ -238,6 +239,12 @@ module ActionController
controller.status = 401
end
+ def secret_token(request)
+ secret = request.env["action_dispatch.secret_token"]
+ raise "You must set config.secret_token in your app's config" if secret.blank?
+ secret
+ end
+
# Uses an MD5 digest based on time to generate a value to be used only once.
#
# A server-specified data string which should be uniquely generated each time a 401 response is made.
diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb
index 29d8523ee1..030ba4ec48 100644
--- a/actionpack/lib/action_controller/railtie.rb
+++ b/actionpack/lib/action_controller/railtie.rb
@@ -51,7 +51,6 @@ module ActionController
ac.assets_dir = paths.public.to_a.first
ac.javascripts_dir = paths.public.javascripts.to_a.first
ac.stylesheets_dir = paths.public.stylesheets.to_a.first
- ac.secret = app.config.cookie_secret
ActiveSupport.on_load(:action_controller) do
self.config.merge!(ac)
diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb
index 71dcac9e94..42ab1d1ebb 100644
--- a/actionpack/lib/action_dispatch/middleware/cookies.rb
+++ b/actionpack/lib/action_dispatch/middleware/cookies.rb
@@ -1,7 +1,9 @@
+require "active_support/core_ext/object/blank"
+
module ActionDispatch
class Request
- def cookie_jar(config = {})
- env['action_dispatch.cookies'] ||= Cookies::CookieJar.build(self, config)
+ def cookie_jar
+ env['action_dispatch.cookies'] ||= Cookies::CookieJar.build(self)
end
end
@@ -51,17 +53,17 @@ module ActionDispatch
# only HTTP. Defaults to +false+.
class Cookies
class CookieJar < Hash #:nodoc:
- def self.build(request, config = {})
- new(config).tap do |hash|
+ def self.build(request)
+ secret = request.env["action_dispatch.secret_token"]
+ new(secret).tap do |hash|
hash.update(request.cookies)
end
end
- def initialize(config = {})
- @config = config
+ def initialize(secret=nil)
+ @secret = secret
@set_cookies = {}
@delete_cookies = {}
-
super()
end
@@ -112,7 +114,7 @@ module ActionDispatch
# cookies.permanent.signed[:remember_me] = current_user.id
# # => Set-Cookie: discount=BAhU--848956038e692d7046deab32b7131856ab20e14e; path=/; expires=Sun, 16-Dec-2029 03:24:16 GMT
def permanent
- @permanent ||= PermanentCookieJar.new(self, @config)
+ @permanent ||= PermanentCookieJar.new(self, @secret)
end
# Returns a jar that'll automatically generate a signed representation of cookie value and verify it when reading from
@@ -120,7 +122,7 @@ module ActionDispatch
# cookie was tampered with by the user (or a 3rd party), an ActiveSupport::MessageVerifier::InvalidSignature exception will
# be raised.
#
- # This jar requires that you set a suitable secret for the verification on your app's config.cookie_secret.
+ # This jar requires that you set a suitable secret for the verification on your app's config.secret_token.
#
# Example:
#
@@ -129,7 +131,7 @@ module ActionDispatch
#
# cookies.signed[:discount] # => 45
def signed
- @signed ||= SignedCookieJar.new(self, @config)
+ @signed ||= SignedCookieJar.new(self, @secret)
end
def write(response)
@@ -139,9 +141,8 @@ module ActionDispatch
end
class PermanentCookieJar < CookieJar #:nodoc:
- def initialize(parent_jar, config = {})
- @parent_jar = parent_jar
- @config = config
+ def initialize(parent_jar, secret)
+ @parent_jar, @secret = parent_jar, secret
end
def []=(key, options)
@@ -156,7 +157,7 @@ module ActionDispatch
end
def signed
- @signed ||= SignedCookieJar.new(self, @config)
+ @signed ||= SignedCookieJar.new(self, @secret)
end
def method_missing(method, *arguments, &block)
@@ -165,11 +166,10 @@ module ActionDispatch
end
class SignedCookieJar < CookieJar #:nodoc:
- def initialize(parent_jar, config = {})
- raise 'Missing cookie signing secret' if config[:signing_secret].blank?
+ def initialize(parent_jar, secret)
+ raise "You must set config.secret_token in your app's config" if secret.blank?
@parent_jar = parent_jar
- @config = config
- @verifier = ActiveSupport::MessageVerifier.new(config[:signing_secret])
+ @verifier = ActiveSupport::MessageVerifier.new(secret)
end
def [](name)
diff --git a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
index 3331b7c25e..88ba941676 100644
--- a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
+++ b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
@@ -192,7 +192,7 @@ module ActionDispatch
if secret.blank?
raise ArgumentError, "A secret is required to generate an " +
"integrity hash for cookie session data. Use " +
- "config.cookie_secret = \"some secret phrase of at " +
+ "config.secret_token = \"some secret phrase of at " +
"least #{SECRET_MIN_LENGTH} characters\"" +
"in config/application.rb"
end
diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb
index 8d107d9aa5..64eb6d8de7 100644
--- a/actionpack/lib/action_dispatch/testing/integration.rb
+++ b/actionpack/lib/action_dispatch/testing/integration.rb
@@ -1,6 +1,6 @@
require 'stringio'
require 'uri'
-require 'active_support/core_ext/object/singleton_class'
+require 'active_support/core_ext/kernel/singleton_class'
require 'rack/test'
require 'test/unit/assertions'
@@ -137,7 +137,10 @@ module ActionDispatch
end
# The hostname used in the last request.
- attr_accessor :host
+ def host
+ @host || DEFAULT_HOST
+ end
+ attr_writer :host
# The remote_addr used in the last request.
attr_accessor :remote_addr
@@ -148,7 +151,7 @@ module ActionDispatch
# A map of the cookies returned by the last response, and which will be
# sent with the next request.
def cookies
- @mock_session.cookie_jar
+ _mock_session.cookie_jar
end
# A reference to the controller instance used by the last request.
@@ -189,8 +192,8 @@ module ActionDispatch
# session.reset!
def reset!
@https = false
- @mock_session = Rack::MockSession.new(@app, DEFAULT_HOST)
@controller = @request = @response = nil
+ @_mock_session = nil
@request_count = 0
self.host = DEFAULT_HOST
@@ -234,6 +237,9 @@ module ActionDispatch
end
private
+ def _mock_session
+ @_mock_session ||= Rack::MockSession.new(@app, host)
+ end
# Performs the actual request.
def process(method, path, parameters = nil, rack_environment = nil)
@@ -254,7 +260,7 @@ module ActionDispatch
:method => method,
:params => parameters,
- "SERVER_NAME" => host,
+ "SERVER_NAME" => host.split(':')[0],
"SERVER_PORT" => (https? ? "443" : "80"),
"HTTPS" => https? ? "on" : "off",
"rack.url_scheme" => https? ? "https" : "http",
@@ -266,17 +272,25 @@ module ActionDispatch
"HTTP_ACCEPT" => accept
}
- session = Rack::Test::Session.new(@mock_session)
+ session = Rack::Test::Session.new(_mock_session)
(rack_environment || {}).each do |key, value|
env[key] = value
end
- session.request(path, env)
+ # NOTE: rack-test v0.5 doesn't build a default uri correctly
+ # Make sure requested path is always a full uri
+ uri = URI.parse('/')
+ uri.scheme ||= env['rack.url_scheme']
+ uri.host ||= env['SERVER_NAME']
+ uri.port ||= env['SERVER_PORT'].try(:to_i)
+ uri += path
+
+ session.request(uri.to_s, env)
@request_count += 1
@request = ActionDispatch::Request.new(session.last_request.env)
- response = @mock_session.last_response
+ response = _mock_session.last_response
@response = ActionDispatch::TestResponse.new(response.status, response.headers, response.body)
@html_document = nil
diff --git a/actionpack/lib/action_dispatch/testing/test_request.rb b/actionpack/lib/action_dispatch/testing/test_request.rb
index 090e03cf44..b3e67f6e36 100644
--- a/actionpack/lib/action_dispatch/testing/test_request.rb
+++ b/actionpack/lib/action_dispatch/testing/test_request.rb
@@ -1,4 +1,5 @@
require 'active_support/core_ext/object/blank'
+require 'active_support/core_ext/hash/reverse_merge'
module ActionDispatch
class TestRequest < Request
@@ -9,6 +10,7 @@ module ActionDispatch
end
def initialize(env = {})
+ env = Rails.application.env_defaults.merge(env) if defined?(Rails.application)
super(DEFAULT_ENV.merge(env))
self.host = 'test.host'
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index 64616f4fce..fc02d959d4 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -300,15 +300,16 @@ module ActionView
case record_or_name_or_array
when String, Symbol
+ ActiveSupport::Deprecation.warn("Using form_for(:name, @resource) is deprecated. Please use form_for(@resource, :as => :name) instead.", caller) unless args.empty?
object_name = record_or_name_or_array
when Array
object = record_or_name_or_array.last
- object_name = ActionController::RecordIdentifier.singular_class_name(object)
+ object_name = options[:as] || ActionController::RecordIdentifier.singular_class_name(object)
apply_form_for_options!(record_or_name_or_array, options)
args.unshift object
else
object = record_or_name_or_array
- object_name = ActionController::RecordIdentifier.singular_class_name(object)
+ object_name = options[:as] || ActionController::RecordIdentifier.singular_class_name(object)
apply_form_for_options!([object], options)
args.unshift object
end
@@ -326,9 +327,13 @@ module ActionView
html_options =
if object.respond_to?(:persisted?) && object.persisted?
- { :class => dom_class(object, :edit), :id => dom_id(object, :edit), :method => :put }
+ { :class => options[:as] ? "#{options[:as]}_edit" : dom_class(object, :edit),
+ :id => options[:as] ? "#{options[:as]}_edit" : dom_id(object, :edit),
+ :method => :put }
else
- { :class => dom_class(object, :new), :id => dom_id(object), :method => :post }
+ { :class => options[:as] ? "#{options[:as]}_new" : dom_class(object, :new),
+ :id => options[:as] ? "#{options[:as]}_new" : dom_id(object),
+ :method => :post }
end
options[:html] ||= {}
@@ -779,6 +784,56 @@ module ActionView
def radio_button(object_name, method, tag_value, options = {})
InstanceTag.new(object_name, method, self, options.delete(:object)).to_radio_button_tag(tag_value, options)
end
+
+ # Returns a text_field of type "search".
+ def search_field(object_name, method, options = {})
+ options = options.stringify_keys
+
+ if options["autosave"]
+ if options["autosave"] == true
+ options["autosave"] = request.host.split(".").reverse.join(".")
+ end
+ options["results"] ||= 10
+ end
+
+ if options["onsearch"]
+ options["incremental"] = true unless options.has_key?("incremental")
+ end
+
+ InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("search", options)
+ end
+
+ # Returns a text_field of 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".
+ 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".
+ def email_field(object_name, method, options = {})
+ InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("email", options)
+ end
+
+ # Returns an input tag of type "number".
+ #
+ # ==== Options
+ # * Accepts same options as number_field_tag
+ def number_field(object_name, method, options = {})
+ InstanceTag.new(object_name, method, self, options.delete(:object)).to_number_field_tag("number", options)
+ end
+
+ # Returns an input tag of type "range".
+ #
+ # ==== Options
+ # * Accepts same options as range_field_tag
+ def range_field(object_name, method, options = {})
+ InstanceTag.new(object_name, method, self, options.delete(:object)).to_number_field_tag("range", options)
+ end
end
module InstanceTagMethods #:nodoc:
@@ -842,6 +897,14 @@ module ActionView
tag("input", options)
end
+ def to_number_field_tag(field_type, options = {})
+ options = options.stringify_keys
+ if range = options.delete("in") || options.delete("within")
+ options.update("min" => range.min, "max" => range.max)
+ end
+ to_input_field_tag(field_type, options)
+ end
+
def to_radio_button_tag(tag_value, options = {})
options = DEFAULT_RADIO_OPTIONS.merge(options.stringify_keys)
options["type"] = "radio"
diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb
index cd6138648f..081c317e0c 100644
--- a/actionpack/lib/action_view/helpers/form_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb
@@ -457,6 +457,69 @@ module ActionView
output.safe_concat("</fieldset>")
end
+ # Creates a text field of type "search".
+ #
+ # ==== Options
+ # * Accepts the same options as text_field_tag.
+ def search_field_tag(name, value = nil, options = {})
+ text_field_tag(name, value, options.stringify_keys.update("type" => "search"))
+ end
+
+ # Creates a text field of type "tel".
+ #
+ # ==== Options
+ # * Accepts the same options as text_field_tag.
+ def telephone_field_tag(name, value = nil, options = {})
+ text_field_tag(name, value, options.stringify_keys.update("type" => "tel"))
+ end
+ alias phone_field_tag telephone_field_tag
+
+ # Creates a text field of type "url".
+ #
+ # ==== Options
+ # * Accepts the same options as text_field_tag.
+ def url_field_tag(name, value = nil, options = {})
+ text_field_tag(name, value, options.stringify_keys.update("type" => "url"))
+ end
+
+ # Creates a text field of type "email".
+ #
+ # ==== Options
+ # * Accepts the same options as text_field_tag.
+ def email_field_tag(name, value = nil, options = {})
+ text_field_tag(name, value, options.stringify_keys.update("type" => "email"))
+ end
+
+ # Creates a number field.
+ #
+ # ==== Options
+ # * <tt>:min</tt> - The minimum acceptable value.
+ # * <tt>:max</tt> - The maximum acceptable value.
+ # * <tt>:in</tt> - A range specifying the <tt>:min</tt> and
+ # <tt>:max</tt> values.
+ # * <tt>:step</tt> - The acceptable value granularity.
+ # * Otherwise accepts the same options as text_field_tag.
+ #
+ # ==== Examples
+ # number_field_tag 'quantity', nil, :in => 1...10
+ # => <input id="quantity" name="quantity" min="1" max="9" />
+ def number_field_tag(name, value = nil, options = {})
+ options = options.stringify_keys
+ options["type"] ||= "number"
+ if range = options.delete("in") || options.delete("within")
+ options.update("min" => range.min, "max" => range.max)
+ end
+ text_field_tag(name, value, options)
+ end
+
+ # Creates a range form element.
+ #
+ # ==== Options
+ # * Accepts the same options as number_field_tag.
+ def range_field_tag(name, value = nil, options = {})
+ number_field_tag(name, value, options.stringify_keys.update("type" => "range"))
+ end
+
private
def html_options_for_form(url_for_options, options, *parameters_for_url)
returning options.stringify_keys do |html_options|
diff --git a/actionpack/test/abstract/abstract_controller_test.rb b/actionpack/test/abstract/abstract_controller_test.rb
index f70d497481..3b5013a47a 100644
--- a/actionpack/test/abstract/abstract_controller_test.rb
+++ b/actionpack/test/abstract/abstract_controller_test.rb
@@ -2,21 +2,21 @@ require 'abstract_unit'
module AbstractController
module Testing
-
+
# Test basic dispatching.
# ====
# * Call process
# * Test that the response_body is set correctly
class SimpleController < AbstractController::Base
end
-
+
class Me < SimpleController
def index
self.response_body = "Hello world"
"Something else"
- end
+ end
end
-
+
class TestBasic < ActiveSupport::TestCase
test "dispatching works" do
controller = Me.new
@@ -24,7 +24,7 @@ module AbstractController
assert_equal "Hello world", controller.response_body
end
end
-
+
# Test Render mixin
# ====
class RenderingController < AbstractController::Base
@@ -36,24 +36,28 @@ module AbstractController
if options.is_a?(String)
options = {:_template_name => options}
end
-
+
options[:_prefix] = _prefix
super
end
append_view_path File.expand_path(File.join(File.dirname(__FILE__), "views"))
end
-
+
class Me2 < RenderingController
def index
render "index.erb"
end
-
+
+ def index_to_string
+ self.response_body = render_to_string "index.erb"
+ end
+
def action_with_ivars
@my_ivar = "Hello"
render "action_with_ivars.erb"
end
-
+
def naked_render
render
end
@@ -76,12 +80,17 @@ module AbstractController
@controller.process(:index)
assert_equal "Hello from index.erb", @controller.response_body
end
-
+
+ test "render_to_string works with a String as an argument" do
+ @controller.process(:index_to_string)
+ assert_equal "Hello from index.erb", @controller.response_body
+ end
+
test "rendering passes ivars to the view" do
@controller.process(:action_with_ivars)
assert_equal "Hello from index_with_ivars.erb", @controller.response_body
end
-
+
test "rendering with no template name" do
@controller.process(:naked_render)
assert_equal "Hello from naked_render.erb", @controller.response_body
@@ -97,7 +106,7 @@ module AbstractController
assert_equal "Hello from naked_render.erb", @controller.response_body
end
end
-
+
# Test rendering with prefixes
# ====
# * self._prefix is used when defined
@@ -106,23 +115,23 @@ module AbstractController
def self.prefix
name.underscore
end
-
+
def _prefix
self.class.prefix
end
end
-
+
class Me3 < PrefixedViews
def index
render
end
-
+
def formatted
self.formats = [:html]
render
end
end
-
+
class TestPrefixedViews < ActiveSupport::TestCase
def setup
@controller = Me3.new
@@ -138,13 +147,13 @@ module AbstractController
assert_equal "Hello from me3/formatted.html.erb", @controller.response_body
end
end
-
+
# Test rendering with layouts
# ====
# self._layout is used when defined
class WithLayouts < PrefixedViews
include Layouts
-
+
private
def self.layout(formats)
begin
@@ -160,21 +169,21 @@ module AbstractController
def render_to_body(options = {})
options[:_layout] = options[:layout] || _default_layout({})
super
- end
+ end
end
-
+
class Me4 < WithLayouts
def index
render
end
end
-
+
class Me5 < WithLayouts
def index
render
end
end
-
+
class TestLayouts < ActiveSupport::TestCase
test "layouts are included" do
controller = Me4.new
@@ -182,7 +191,7 @@ module AbstractController
assert_equal "Me4 Enter : Hello from me4/index.erb : Exit", controller.response_body
end
end
-
+
# respond_to_action?(action_name)
# ====
# * A method can be used as an action only if this method
@@ -191,7 +200,7 @@ module AbstractController
class DefaultRespondToActionController < AbstractController::Base
def index() self.response_body = "success" end
end
-
+
class ActionMissingRespondToActionController < AbstractController::Base
# No actions
private
@@ -199,19 +208,19 @@ module AbstractController
self.response_body = "success"
end
end
-
+
class RespondToActionController < AbstractController::Base;
def index() self.response_body = "success" end
-
+
def fail() self.response_body = "fail" end
-
+
private
def method_for_action(action_name)
action_name.to_s != "fail" && action_name
end
end
-
+
class TestRespondToAction < ActiveSupport::TestCase
def assert_dispatch(klass, body = "success", action = :index)
@@ -219,27 +228,27 @@ module AbstractController
controller.process(action)
assert_equal body, controller.response_body
end
-
+
test "an arbitrary method is available as an action by default" do
assert_dispatch DefaultRespondToActionController, "success", :index
end
-
+
test "raises ActionNotFound when method does not exist and action_missing is not defined" do
assert_raise(ActionNotFound) { DefaultRespondToActionController.new.process(:fail) }
end
-
+
test "dispatches to action_missing when method does not exist and action_missing is defined" do
assert_dispatch ActionMissingRespondToActionController, "success", :ohai
end
-
+
test "a method is available as an action if respond_to_action? returns true" do
assert_dispatch RespondToActionController, "success", :index
end
-
+
test "raises ActionNotFound if method is defined but respond_to_action? returns false" do
assert_raise(ActionNotFound) { RespondToActionController.new.process(:fail) }
end
end
-
+
end
end
diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb
index fe78b8ec1f..acf887ee4a 100644
--- a/actionpack/test/abstract_unit.rb
+++ b/actionpack/test/abstract_unit.rb
@@ -192,10 +192,6 @@ end
# Temporary base class
class Rack::TestCase < ActionController::IntegrationTest
- setup do
- ActionController::Base.config.secret = "abc" * 30
- end
-
def self.testing(klass = nil)
if klass
@testing = "/#{klass.name.underscore}".sub!(/_controller$/, '')
diff --git a/actionpack/test/controller/cookie_test.rb b/actionpack/test/controller/cookie_test.rb
index 278cae1415..4971866e7c 100644
--- a/actionpack/test/controller/cookie_test.rb
+++ b/actionpack/test/controller/cookie_test.rb
@@ -1,7 +1,5 @@
require 'abstract_unit'
-ActionController::Base.config.secret = "thisISverySECRET123"
-
class CookieTest < ActionController::TestCase
class TestController < ActionController::Base
def authenticate
@@ -76,6 +74,7 @@ class CookieTest < ActionController::TestCase
def setup
super
+ @request.env["action_dispatch.secret_token"] = "thisISverySECRET123"
@request.host = "www.nextangle.com"
end
diff --git a/actionpack/test/controller/http_digest_authentication_test.rb b/actionpack/test/controller/http_digest_authentication_test.rb
index eb2af523a2..b011536717 100644
--- a/actionpack/test/controller/http_digest_authentication_test.rb
+++ b/actionpack/test/controller/http_digest_authentication_test.rb
@@ -41,8 +41,7 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
setup do
# Used as secret in generating nonce to prevent tampering of timestamp
@secret = "session_options_secret"
- @controller.config.secret = @secret
- # @old_secret, ActionController::Base.config.secret[:secret] = ActionController::Base.session_options[:secret], @secret
+ @request.env["action_dispatch.secret_token"] = @secret
end
teardown do
@@ -206,7 +205,7 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
test "validate_digest_response should fail with nil returning password_procedure" do
@request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => nil, :password => nil)
- assert !ActionController::HttpAuthentication::Digest.validate_digest_response(@secret, @request, "SuperSecret"){nil}
+ assert !ActionController::HttpAuthentication::Digest.validate_digest_response(@request, "SuperSecret"){nil}
end
private
diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb
index 14c0c3708b..20dc96d38d 100644
--- a/actionpack/test/controller/integration_test.rb
+++ b/actionpack/test/controller/integration_test.rb
@@ -245,6 +245,15 @@ class IntegrationProcessTest < ActionController::IntegrationTest
render :text => "Gone", :status => 410
end
+ def set_cookie
+ cookies["foo"] = 'bar'
+ head :ok
+ end
+
+ def get_cookie
+ render :text => cookies["foo"]
+ end
+
def redirect
redirect_to :action => "get"
end
@@ -292,6 +301,42 @@ class IntegrationProcessTest < ActionController::IntegrationTest
end
end
+ test 'cookie persist to next request' do
+ with_test_route_set do
+ get '/set_cookie'
+ assert_response :success
+
+ assert_equal "foo=bar; path=/", headers["Set-Cookie"]
+ assert_equal({"foo"=>"bar"}, cookies.to_hash)
+
+ get '/get_cookie'
+ assert_response :success
+ assert_equal "bar", body
+
+ assert_equal nil, headers["Set-Cookie"]
+ assert_equal({"foo"=>"bar"}, cookies.to_hash)
+ end
+ end
+
+ test 'cookie persist to next request on another domain' do
+ with_test_route_set do
+ host! "37s.backpack.test"
+
+ get '/set_cookie'
+ assert_response :success
+
+ assert_equal "foo=bar; path=/", headers["Set-Cookie"]
+ assert_equal({"foo"=>"bar"}, cookies.to_hash)
+
+ get '/get_cookie'
+ assert_response :success
+ assert_equal "bar", body
+
+ assert_equal nil, headers["Set-Cookie"]
+ assert_equal({"foo"=>"bar"}, cookies.to_hash)
+ end
+ end
+
def test_redirect
with_test_route_set do
get '/redirect'
diff --git a/actionpack/test/template/erb/form_for_test.rb b/actionpack/test/template/erb/form_for_test.rb
index 482dbb0287..ec6e872735 100644
--- a/actionpack/test/template/erb/form_for_test.rb
+++ b/actionpack/test/template/erb/form_for_test.rb
@@ -8,4 +8,4 @@ module ERBTest
assert_equal "<form action=\"/blah/update\" method=\"post\"></form>", output
end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb
index 4af38e52dd..64dfbde0b0 100644
--- a/actionpack/test/template/form_helper_test.rb
+++ b/actionpack/test/template/form_helper_test.rb
@@ -349,6 +349,36 @@ class FormHelperTest < ActionView::TestCase
)
end
+ def test_search_field
+ expected = %{<input id="contact_notes_query" size="30" name="contact[notes_query]" type="search" />}
+ assert_dom_equal(expected, search_field("contact", "notes_query"))
+ end
+
+ def test_telephone_field
+ expected = %{<input id="user_cell" size="30" name="user[cell]" type="tel" />}
+ assert_dom_equal(expected, telephone_field("user", "cell"))
+ end
+
+ def test_url_field
+ expected = %{<input id="user_homepage" size="30" name="user[homepage]" type="url" />}
+ assert_dom_equal(expected, url_field("user", "homepage"))
+ end
+
+ def test_email_field
+ expected = %{<input id="user_address" size="30" name="user[address]" type="email" />}
+ assert_dom_equal(expected, email_field("user", "address"))
+ end
+
+ def test_number_field
+ expected = %{<input name="order[quantity]" size="30" max="9" id="order_quantity" type="number" min="1" />}
+ assert_dom_equal(expected, number_field("order", "quantity", :in => 1...10))
+ end
+
+ def test_range_input
+ expected = %{<input name="hifi[volume]" step="0.1" size="30" max="11" id="hifi_volume" type="range" min="0" />}
+ assert_dom_equal(expected, range_field("hifi", "volume", :in => 0..11, :step => 0.1))
+ end
+
def test_explicit_name
assert_dom_equal(
'<input id="post_title" name="dont guess" size="30" type="text" value="Hello World" />', text_field("post", "title", "name" => "dont guess")
@@ -416,12 +446,14 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for
- form_for(:post, @post, :html => { :id => 'create-post' }) do |f|
- concat f.label(:title)
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
- concat f.submit('Create post')
+ assert_deprecated do
+ form_for(:post, @post, :html => { :id => 'create-post' }) do |f|
+ concat f.label(:title)
+ concat f.text_field(:title)
+ concat f.text_area(:body)
+ concat f.check_box(:secret)
+ concat f.submit('Create post')
+ end
end
expected =
@@ -437,11 +469,35 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal expected, output_buffer
end
- def test_form_for_with_method
- form_for(:post, @post, :html => { :id => 'create-post', :method => :put }) do |f|
+ def test_form_for_with_symbol_object_name
+ form_for(@post, :as => "other_name", :html => { :id => 'create-post' }) do |f|
+ concat f.label(:title)
concat f.text_field(:title)
concat f.text_area(:body)
concat f.check_box(:secret)
+ concat f.submit('Create post')
+ end
+
+ expected =
+ "<form class='other_name_edit' method='post' action='/posts/123' id='create-post'>" +
+ "<div style='margin:0;padding:0;display:inline'><input name='_method' value='put' type='hidden' /></div>" +
+ "<label for='other_name_title'>Title</label>" +
+ "<input name='other_name[title]' size='30' id='other_name_title' value='Hello World' type='text' />" +
+ "<textarea name='other_name[body]' id='other_name_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
+ "<input name='other_name[secret]' value='0' type='hidden' />" +
+ "<input name='other_name[secret]' checked='checked' id='other_name_secret' value='1' type='checkbox' />" +
+ "<input name='commit' id='other_name_submit' value='Create post' type='submit' /></form>"
+
+ assert_dom_equal expected, output_buffer
+ end
+
+ def test_form_for_with_method
+ assert_deprecated do
+ form_for(:post, @post, :html => { :id => 'create-post', :method => :put }) do |f|
+ concat f.text_field(:title)
+ concat f.text_area(:body)
+ concat f.check_box(:secret)
+ end
end
expected =
@@ -457,10 +513,12 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_with_remote
- form_for(:post, @post, :remote => true, :html => { :id => 'create-post', :method => :put }) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
+ assert_deprecated do
+ form_for(:post, @post, :remote => true, :html => { :id => 'create-post', :method => :put }) do |f|
+ concat f.text_field(:title)
+ concat f.text_area(:body)
+ concat f.check_box(:secret)
+ end
end
expected =
@@ -494,16 +552,18 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_with_index
- form_for("post[]", @post) do |f|
- concat f.label(:title)
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
+ assert_deprecated do
+ form_for("post[]", @post) do |f|
+ concat f.label(:title)
+ concat f.text_field(:title)
+ concat f.text_area(:body)
+ concat f.check_box(:secret)
+ end
end
expected =
"<form action='http://www.example.com' method='post'>" +
- "<label for=\"post_123_title\">Title</label>" +
+ "<label for='post_123_title'>Title</label>" +
"<input name='post[123][title]' size='30' type='text' id='post_123_title' value='Hello World' />" +
"<textarea name='post[123][body]' id='post_123_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
"<input name='post[123][secret]' type='hidden' value='0' />" +
@@ -514,10 +574,12 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_with_nil_index_option_override
- form_for("post[]", @post, :index => nil) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
+ assert_deprecated do
+ form_for("post[]", @post, :index => nil) do |f|
+ concat f.text_field(:title)
+ concat f.text_area(:body)
+ concat f.check_box(:secret)
+ end
end
expected =
@@ -535,8 +597,10 @@ class FormHelperTest < ActionView::TestCase
old_locale, I18n.locale = I18n.locale, :submit
@post.persisted = false
- form_for(:post, @post) do |f|
- concat f.submit
+ assert_deprecated do
+ form_for(:post, @post) do |f|
+ concat f.submit
+ end
end
expected = "<form action='http://www.example.com' method='post'>" +
@@ -550,8 +614,10 @@ class FormHelperTest < ActionView::TestCase
def test_submit_with_object_as_existing_record_and_locale_strings
old_locale, I18n.locale = I18n.locale, :submit
- form_for(:post, @post) do |f|
- concat f.submit
+ assert_deprecated do
+ form_for(:post, @post) do |f|
+ concat f.submit
+ end
end
expected = "<form action='http://www.example.com' method='post'>" +
@@ -580,8 +646,10 @@ class FormHelperTest < ActionView::TestCase
def test_submit_with_object_and_nested_lookup
old_locale, I18n.locale = I18n.locale, :submit
- form_for(:another_post, @post) do |f|
- concat f.submit
+ assert_deprecated do
+ form_for(:another_post, @post) do |f|
+ concat f.submit
+ end
end
expected = "<form action='http://www.example.com' method='post'>" +
@@ -593,10 +661,12 @@ class FormHelperTest < ActionView::TestCase
end
def test_nested_fields_for
- form_for(:post, @post) do |f|
- concat f.fields_for(:comment, @post) { |c|
- concat c.text_field(:title)
- }
+ assert_deprecated do
+ form_for(:post, @post) do |f|
+ concat f.fields_for(:comment, @post) { |c|
+ concat c.text_field(:title)
+ }
+ end
end
expected = "<form action='http://www.example.com' method='post'>" +
@@ -607,11 +677,13 @@ class FormHelperTest < ActionView::TestCase
end
def test_nested_fields_for_with_nested_collections
- form_for('post[]', @post) do |f|
- concat f.text_field(:title)
- concat f.fields_for('comment[]', @comment) { |c|
- concat c.text_field(:name)
- }
+ assert_deprecated do
+ form_for('post[]', @post) do |f|
+ concat f.text_field(:title)
+ concat f.fields_for('comment[]', @comment) { |c|
+ concat c.text_field(:name)
+ }
+ end
end
expected = "<form action='http://www.example.com' method='post'>" +
@@ -623,11 +695,13 @@ class FormHelperTest < ActionView::TestCase
end
def test_nested_fields_for_with_index_and_parent_fields
- form_for('post', @post, :index => 1) do |c|
- concat c.text_field(:title)
- concat c.fields_for('comment', @comment, :index => 1) { |r|
- concat r.text_field(:name)
- }
+ assert_deprecated do
+ form_for('post', @post, :index => 1) do |c|
+ concat c.text_field(:title)
+ concat c.fields_for('comment', @comment, :index => 1) { |r|
+ concat r.text_field(:name)
+ }
+ end
end
expected = "<form action='http://www.example.com' method='post'>" +
@@ -639,10 +713,12 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_with_index_and_nested_fields_for
- output_buffer = form_for(:post, @post, :index => 1) do |f|
- concat f.fields_for(:comment, @post) { |c|
- concat c.text_field(:title)
- }
+ assert_deprecated do
+ output_buffer = form_for(:post, @post, :index => 1) do |f|
+ concat f.fields_for(:comment, @post) { |c|
+ concat c.text_field(:title)
+ }
+ end
end
expected = "<form action='http://www.example.com' method='post'>" +
@@ -653,10 +729,12 @@ class FormHelperTest < ActionView::TestCase
end
def test_nested_fields_for_with_index_on_both
- form_for(:post, @post, :index => 1) do |f|
- concat f.fields_for(:comment, @post, :index => 5) { |c|
- concat c.text_field(:title)
- }
+ assert_deprecated do
+ form_for(:post, @post, :index => 1) do |f|
+ concat f.fields_for(:comment, @post, :index => 5) { |c|
+ concat c.text_field(:title)
+ }
+ end
end
expected = "<form action='http://www.example.com' method='post'>" +
@@ -667,10 +745,12 @@ class FormHelperTest < ActionView::TestCase
end
def test_nested_fields_for_with_auto_index
- form_for("post[]", @post) do |f|
- concat f.fields_for(:comment, @post) { |c|
- concat c.text_field(:title)
- }
+ assert_deprecated do
+ form_for("post[]", @post) do |f|
+ concat f.fields_for(:comment, @post) { |c|
+ concat c.text_field(:title)
+ }
+ end
end
expected = "<form action='http://www.example.com' method='post'>" +
@@ -681,10 +761,12 @@ class FormHelperTest < ActionView::TestCase
end
def test_nested_fields_for_with_index_radio_button
- form_for(:post, @post) do |f|
- concat f.fields_for(:comment, @post, :index => 5) { |c|
- concat c.radio_button(:title, "hello")
- }
+ assert_deprecated do
+ form_for(:post, @post) do |f|
+ concat f.fields_for(:comment, @post, :index => 5) { |c|
+ concat c.radio_button(:title, "hello")
+ }
+ end
end
expected = "<form action='http://www.example.com' method='post'>" +
@@ -695,10 +777,12 @@ class FormHelperTest < ActionView::TestCase
end
def test_nested_fields_for_with_auto_index_on_both
- form_for("post[]", @post) do |f|
- concat f.fields_for("comment[]", @post) { |c|
- concat c.text_field(:title)
- }
+ assert_deprecated do
+ form_for("post[]", @post) do |f|
+ concat f.fields_for("comment[]", @post) { |c|
+ concat c.text_field(:title)
+ }
+ end
end
expected = "<form action='http://www.example.com' method='post'>" +
@@ -709,36 +793,40 @@ class FormHelperTest < ActionView::TestCase
end
def test_nested_fields_for_with_index_and_auto_index
- output_buffer = form_for("post[]", @post) do |f|
- concat f.fields_for(:comment, @post, :index => 5) { |c|
- concat c.text_field(:title)
- }
- end
+ assert_deprecated do
+ output_buffer = form_for("post[]", @post) do |f|
+ concat f.fields_for(:comment, @post, :index => 5) { |c|
+ concat c.text_field(:title)
+ }
+ end
- output_buffer << form_for(:post, @post, :index => 1) do |f|
- concat f.fields_for("comment[]", @post) { |c|
- concat c.text_field(:title)
- }
- end
+ output_buffer << form_for(:post, @post, :index => 1) do |f|
+ concat f.fields_for("comment[]", @post) { |c|
+ concat c.text_field(:title)
+ }
+ end
- expected = "<form action='http://www.example.com' method='post'>" +
- "<input name='post[123][comment][5][title]' size='30' type='text' id='post_123_comment_5_title' value='Hello World' />" +
- "</form>" +
- "<form action='http://www.example.com' method='post'>" +
- "<input name='post[1][comment][123][title]' size='30' type='text' id='post_1_comment_123_title' value='Hello World' />" +
- "</form>"
+ expected = "<form action='http://www.example.com' method='post'>" +
+ "<input name='post[123][comment][5][title]' size='30' type='text' id='post_123_comment_5_title' value='Hello World' />" +
+ "</form>" +
+ "<form action='http://www.example.com' method='post'>" +
+ "<input name='post[1][comment][123][title]' size='30' type='text' id='post_1_comment_123_title' value='Hello World' />" +
+ "</form>"
- assert_dom_equal expected, output_buffer
+ assert_dom_equal expected, output_buffer
+ end
end
def test_nested_fields_for_with_a_new_record_on_a_nested_attributes_one_to_one_association
@post.author = Author.new
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- concat f.fields_for(:author) { |af|
- concat af.text_field(:name)
- }
+ assert_deprecated do
+ form_for(:post, @post) do |f|
+ concat f.text_field(:title)
+ concat f.fields_for(:author) { |af|
+ concat af.text_field(:name)
+ }
+ end
end
expected = '<form action="http://www.example.com" method="post">' +
@@ -750,10 +838,12 @@ class FormHelperTest < ActionView::TestCase
end
def test_nested_fields_for_with_explicitly_passed_object_on_a_nested_attributes_one_to_one_association
- form_for(:post, @post) do |f|
- f.fields_for(:author, Author.new(123)) do |af|
- assert_not_nil af.object
- assert_equal 123, af.object.id
+ assert_deprecated do
+ form_for(:post, @post) do |f|
+ f.fields_for(:author, Author.new(123)) do |af|
+ assert_not_nil af.object
+ assert_equal 123, af.object.id
+ end
end
end
end
@@ -761,11 +851,13 @@ class FormHelperTest < ActionView::TestCase
def test_nested_fields_for_with_an_existing_record_on_a_nested_attributes_one_to_one_association
@post.author = Author.new(321)
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- concat f.fields_for(:author) { |af|
- concat af.text_field(:name)
- }
+ assert_deprecated do
+ form_for(:post, @post) do |f|
+ concat f.text_field(:title)
+ concat f.fields_for(:author) { |af|
+ concat af.text_field(:name)
+ }
+ end
end
expected = '<form action="http://www.example.com" method="post">' +
@@ -780,12 +872,14 @@ class FormHelperTest < ActionView::TestCase
def test_nested_fields_for_with_existing_records_on_a_nested_attributes_one_to_one_association_with_explicit_hidden_field_placement
@post.author = Author.new(321)
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- concat f.fields_for(:author) { |af|
- concat af.hidden_field(:id)
- concat af.text_field(:name)
- }
+ assert_deprecated do
+ form_for(:post, @post) do |f|
+ concat f.text_field(:title)
+ concat f.fields_for(:author) { |af|
+ concat af.hidden_field(:id)
+ concat af.text_field(:name)
+ }
+ end
end
expected = '<form action="http://www.example.com" method="post">' +
@@ -800,12 +894,14 @@ class FormHelperTest < ActionView::TestCase
def test_nested_fields_for_with_existing_records_on_a_nested_attributes_collection_association
@post.comments = Array.new(2) { |id| Comment.new(id + 1) }
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- @post.comments.each do |comment|
- concat f.fields_for(:comments, comment) { |cf|
- concat cf.text_field(:name)
- }
+ assert_deprecated do
+ form_for(:post, @post) do |f|
+ concat f.text_field(:title)
+ @post.comments.each do |comment|
+ concat f.fields_for(:comments, comment) { |cf|
+ concat cf.text_field(:name)
+ }
+ end
end
end
@@ -823,13 +919,15 @@ class FormHelperTest < ActionView::TestCase
def test_nested_fields_for_with_existing_records_on_a_nested_attributes_collection_association_with_explicit_hidden_field_placement
@post.comments = Array.new(2) { |id| Comment.new(id + 1) }
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- @post.comments.each do |comment|
- concat f.fields_for(:comments, comment) { |cf|
- concat cf.hidden_field(:id)
- concat cf.text_field(:name)
- }
+ assert_deprecated do
+ form_for(:post, @post) do |f|
+ concat f.text_field(:title)
+ @post.comments.each do |comment|
+ concat f.fields_for(:comments, comment) { |cf|
+ concat cf.hidden_field(:id)
+ concat cf.text_field(:name)
+ }
+ end
end
end
@@ -847,12 +945,14 @@ class FormHelperTest < ActionView::TestCase
def test_nested_fields_for_with_new_records_on_a_nested_attributes_collection_association
@post.comments = [Comment.new, Comment.new]
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- @post.comments.each do |comment|
- concat f.fields_for(:comments, comment) { |cf|
- concat cf.text_field(:name)
- }
+ assert_deprecated do
+ form_for(:post, @post) do |f|
+ concat f.text_field(:title)
+ @post.comments.each do |comment|
+ concat f.fields_for(:comments, comment) { |cf|
+ concat cf.text_field(:name)
+ }
+ end
end
end
@@ -868,12 +968,14 @@ class FormHelperTest < ActionView::TestCase
def test_nested_fields_for_with_existing_and_new_records_on_a_nested_attributes_collection_association
@post.comments = [Comment.new(321), Comment.new]
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- @post.comments.each do |comment|
- concat f.fields_for(:comments, comment) { |cf|
- concat cf.text_field(:name)
- }
+ assert_deprecated do
+ form_for(:post, @post) do |f|
+ concat f.text_field(:title)
+ @post.comments.each do |comment|
+ concat f.fields_for(:comments, comment) { |cf|
+ concat cf.text_field(:name)
+ }
+ end
end
end
@@ -888,10 +990,12 @@ class FormHelperTest < ActionView::TestCase
end
def test_nested_fields_for_with_an_empty_supplied_attributes_collection
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- f.fields_for(:comments, []) do |cf|
- concat cf.text_field(:name)
+ assert_deprecated do
+ form_for(:post, @post) do |f|
+ concat f.text_field(:title)
+ f.fields_for(:comments, []) do |cf|
+ concat cf.text_field(:name)
+ end
end
end
@@ -905,11 +1009,13 @@ class FormHelperTest < ActionView::TestCase
def test_nested_fields_for_with_existing_records_on_a_supplied_nested_attributes_collection
@post.comments = Array.new(2) { |id| Comment.new(id + 1) }
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- concat f.fields_for(:comments, @post.comments) { |cf|
- concat cf.text_field(:name)
- }
+ assert_deprecated do
+ form_for(:post, @post) do |f|
+ concat f.text_field(:title)
+ concat f.fields_for(:comments, @post.comments) { |cf|
+ concat cf.text_field(:name)
+ }
+ end
end
expected = '<form action="http://www.example.com" method="post">' +
@@ -927,11 +1033,13 @@ class FormHelperTest < ActionView::TestCase
comments = Array.new(2) { |id| Comment.new(id + 1) }
@post.comments = []
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- concat f.fields_for(:comments, comments) { |cf|
- concat cf.text_field(:name)
- }
+ assert_deprecated do
+ form_for(:post, @post) do |f|
+ concat f.text_field(:title)
+ concat f.fields_for(:comments, comments) { |cf|
+ concat cf.text_field(:name)
+ }
+ end
end
expected = '<form action="http://www.example.com" method="post">' +
@@ -949,12 +1057,14 @@ class FormHelperTest < ActionView::TestCase
@post.comments = [Comment.new(321), Comment.new]
yielded_comments = []
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- concat f.fields_for(:comments) { |cf|
- concat cf.text_field(:name)
- yielded_comments << cf.object
- }
+ assert_deprecated do
+ form_for(:post, @post) do |f|
+ concat f.text_field(:title)
+ concat f.fields_for(:comments) { |cf|
+ concat cf.text_field(:name)
+ yielded_comments << cf.object
+ }
+ end
end
expected = '<form action="http://www.example.com" method="post">' +
@@ -971,10 +1081,12 @@ class FormHelperTest < ActionView::TestCase
def test_nested_fields_for_with_child_index_option_override_on_a_nested_attributes_collection_association
@post.comments = []
- form_for(:post, @post) do |f|
- concat f.fields_for(:comments, Comment.new(321), :child_index => 'abc') { |cf|
- concat cf.text_field(:name)
- }
+ assert_deprecated do
+ form_for(:post, @post) do |f|
+ concat f.fields_for(:comments, Comment.new(321), :child_index => 'abc') { |cf|
+ concat cf.text_field(:name)
+ }
+ end
end
expected = '<form action="http://www.example.com" method="post">' +
@@ -991,25 +1103,28 @@ class FormHelperTest < ActionView::TestCase
@post.comments[0].relevances = []
@post.tags[0].relevances = []
@post.tags[1].relevances = []
- form_for(:post, @post) do |f|
- concat f.fields_for(:comments, @post.comments[0]) { |cf|
- concat cf.text_field(:name)
- concat cf.fields_for(:relevances, CommentRelevance.new(314)) { |crf|
- concat crf.text_field(:value)
+
+ assert_deprecated do
+ form_for(:post, @post) do |f|
+ concat f.fields_for(:comments, @post.comments[0]) { |cf|
+ concat cf.text_field(:name)
+ concat cf.fields_for(:relevances, CommentRelevance.new(314)) { |crf|
+ concat crf.text_field(:value)
+ }
}
- }
- concat f.fields_for(:tags, @post.tags[0]) { |tf|
- concat tf.text_field(:value)
- concat tf.fields_for(:relevances, TagRelevance.new(3141)) { |trf|
- concat trf.text_field(:value)
+ concat f.fields_for(:tags, @post.tags[0]) { |tf|
+ concat tf.text_field(:value)
+ concat tf.fields_for(:relevances, TagRelevance.new(3141)) { |trf|
+ concat trf.text_field(:value)
+ }
}
- }
- concat f.fields_for('tags', @post.tags[1]) { |tf|
- concat tf.text_field(:value)
- concat tf.fields_for(:relevances, TagRelevance.new(31415)) { |trf|
- concat trf.text_field(:value)
+ concat f.fields_for('tags', @post.tags[1]) { |tf|
+ concat tf.text_field(:value)
+ concat tf.fields_for(:relevances, TagRelevance.new(31415)) { |trf|
+ concat trf.text_field(:value)
+ }
}
- }
+ end
end
expected = '<form action="http://www.example.com" method="post">' +
@@ -1153,13 +1268,15 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_and_fields_for
- form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
- concat post_form.text_field(:title)
- concat post_form.text_area(:body)
+ assert_deprecated do
+ form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
+ concat post_form.text_field(:title)
+ concat post_form.text_area(:body)
- concat fields_for(:parent_post, @post) { |parent_fields|
- concat parent_fields.check_box(:secret)
- }
+ concat fields_for(:parent_post, @post) { |parent_fields|
+ concat parent_fields.check_box(:secret)
+ }
+ end
end
expected =
@@ -1174,13 +1291,15 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_and_fields_for_with_object
- form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
- concat post_form.text_field(:title)
- concat post_form.text_area(:body)
+ assert_deprecated do
+ form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
+ concat post_form.text_field(:title)
+ concat post_form.text_area(:body)
- concat post_form.fields_for(@comment) { |comment_fields|
- concat comment_fields.text_field(:name)
- }
+ concat post_form.fields_for(@comment) { |comment_fields|
+ concat comment_fields.text_field(:name)
+ }
+ end
end
expected =
@@ -1205,10 +1324,12 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_with_labelled_builder
- form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
+ assert_deprecated do
+ form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
+ concat f.text_field(:title)
+ concat f.text_area(:body)
+ concat f.check_box(:secret)
+ end
end
expected =
@@ -1225,10 +1346,12 @@ class FormHelperTest < ActionView::TestCase
old_default_form_builder, ActionView::Base.default_form_builder =
ActionView::Base.default_form_builder, LabelledFormBuilder
- form_for(:post, @post) do |f|
- concat f.text_field(:title)
- concat f.text_area(:body)
- concat f.check_box(:secret)
+ assert_deprecated do
+ form_for(:post, @post) do |f|
+ concat f.text_field(:title)
+ concat f.text_area(:body)
+ concat f.check_box(:secret)
+ end
end
expected =
@@ -1244,9 +1367,11 @@ class FormHelperTest < ActionView::TestCase
end
def test_default_form_builder_with_active_record_helpers
- form_for(:post, @post) do |f|
- concat f.error_message_on('author_name')
- concat f.error_messages
+ assert_deprecated do
+ form_for(:post, @post) do |f|
+ concat f.error_message_on('author_name')
+ concat f.error_messages
+ end
end
expected = %(<form action='http://www.example.com' method='post'>) +
@@ -1262,9 +1387,11 @@ class FormHelperTest < ActionView::TestCase
post = @post
@post = nil
- form_for(:post, post) do |f|
- concat f.error_message_on('author_name')
- concat f.error_messages
+ assert_deprecated do
+ form_for(:post, post) do |f|
+ concat f.error_message_on('author_name')
+ concat f.error_messages
+ end
end
expected = %(<form action='http://www.example.com' method='post'>) +
@@ -1294,10 +1421,12 @@ class FormHelperTest < ActionView::TestCase
def test_form_for_with_labelled_builder_with_nested_fields_for_without_options_hash
klass = nil
- form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
- f.fields_for(:comments, Comment.new) do |nested_fields|
- klass = nested_fields.class
- ''
+ assert_deprecated do
+ form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
+ f.fields_for(:comments, Comment.new) do |nested_fields|
+ klass = nested_fields.class
+ ''
+ end
end
end
@@ -1307,10 +1436,12 @@ class FormHelperTest < ActionView::TestCase
def test_form_for_with_labelled_builder_with_nested_fields_for_with_options_hash
klass = nil
- form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
- f.fields_for(:comments, Comment.new, :index => 'foo') do |nested_fields|
- klass = nested_fields.class
- ''
+ assert_deprecated do
+ form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
+ f.fields_for(:comments, Comment.new, :index => 'foo') do |nested_fields|
+ klass = nested_fields.class
+ ''
+ end
end
end
@@ -1322,10 +1453,12 @@ class FormHelperTest < ActionView::TestCase
def test_form_for_with_labelled_builder_with_nested_fields_for_with_custom_builder
klass = nil
- form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
- f.fields_for(:comments, Comment.new, :builder => LabelledFormBuilderSubclass) do |nested_fields|
- klass = nested_fields.class
- ''
+ assert_deprecated do
+ form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
+ f.fields_for(:comments, Comment.new, :builder => LabelledFormBuilderSubclass) do |nested_fields|
+ klass = nested_fields.class
+ ''
+ end
end
end
@@ -1333,27 +1466,35 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_with_html_options_adds_options_to_form_tag
- form_for(:post, @post, :html => {:id => 'some_form', :class => 'some_class'}) do |f| end
+ assert_deprecated do
+ form_for(:post, @post, :html => {:id => 'some_form', :class => 'some_class'}) do |f| end
+ end
expected = "<form action=\"http://www.example.com\" class=\"some_class\" id=\"some_form\" method=\"post\"></form>"
assert_dom_equal expected, output_buffer
end
def test_form_for_with_string_url_option
- form_for(:post, @post, :url => 'http://www.otherdomain.com') do |f| end
+ assert_deprecated do
+ form_for(:post, @post, :url => 'http://www.otherdomain.com') do |f| end
+ end
assert_equal '<form action="http://www.otherdomain.com" method="post"></form>', output_buffer
end
def test_form_for_with_hash_url_option
- form_for(:post, @post, :url => {:controller => 'controller', :action => 'action'}) do |f| end
+ assert_deprecated do
+ form_for(:post, @post, :url => {:controller => 'controller', :action => 'action'}) do |f| end
+ end
assert_equal 'controller', @url_for_options[:controller]
assert_equal 'action', @url_for_options[:action]
end
def test_form_for_with_record_url_option
- form_for(:post, @post, :url => @post) do |f| end
+ assert_deprecated do
+ form_for(:post, @post, :url => @post) do |f| end
+ end
expected = "<form action=\"/posts/123\" method=\"post\"></form>"
assert_equal expected, output_buffer
diff --git a/actionpack/test/template/form_tag_helper_test.rb b/actionpack/test/template/form_tag_helper_test.rb
index 3b8760351e..ef612b879b 100644
--- a/actionpack/test/template/form_tag_helper_test.rb
+++ b/actionpack/test/template/form_tag_helper_test.rb
@@ -335,6 +335,36 @@ class FormTagHelperTest < ActionView::TestCase
)
end
+ def test_search_field_tag
+ expected = %{<input id="query" name="query" type="search" />}
+ assert_dom_equal(expected, search_field_tag("query"))
+ end
+
+ def telephone_field_tag
+ expected = %{<input id="cell" name="cell" type="tel" />}
+ assert_dom_equal(expected, telephone_field_tag("cell"))
+ end
+
+ def test_url_field_tag
+ expected = %{<input id="homepage" name="homepage" type="url" />}
+ assert_dom_equal(expected, url_field_tag("homepage"))
+ end
+
+ def test_email_field_tag
+ expected = %{<input id="address" name="address" type="email" />}
+ assert_dom_equal(expected, email_field_tag("address"))
+ end
+
+ def test_number_field_tag
+ expected = %{<input name="quantity" max="9" id="quantity" type="number" min="1" />}
+ assert_dom_equal(expected, number_field_tag("quantity", nil, :in => 1...10))
+ end
+
+ def test_range_input_tag
+ expected = %{<input name="volume" step="0.1" max="11" id="volume" type="range" min="0" />}
+ assert_dom_equal(expected, range_field_tag("volume", nil, :in => 0..11, :step => 0.1))
+ end
+
def test_pass
assert_equal 1, 1
end