diff options
author | Xavier Noria <fxn@hashref.com> | 2010-04-06 15:38:05 -0700 |
---|---|---|
committer | Xavier Noria <fxn@hashref.com> | 2010-04-06 15:38:05 -0700 |
commit | 4c4fd1a60ff1c060e76e9ee540074756510f53ea (patch) | |
tree | 77da1c66c127e36c8b00825b676d9267a9ef4cd6 /actionpack | |
parent | 03cb74b9461293b96ae0add8ff5efda132dabba0 (diff) | |
parent | af130575249571464ec984efa84fcea1267e8cf8 (diff) | |
download | rails-4c4fd1a60ff1c060e76e9ee540074756510f53ea.tar.gz rails-4c4fd1a60ff1c060e76e9ee540074756510f53ea.tar.bz2 rails-4c4fd1a60ff1c060e76e9ee540074756510f53ea.zip |
Merge commit 'rails/master'
Diffstat (limited to 'actionpack')
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 |