aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/CHANGELOG.md106
-rw-r--r--actionpack/RUNNING_UNIT_TESTS.rdoc (renamed from actionpack/RUNNING_UNIT_TESTS)0
-rw-r--r--actionpack/actionpack.gemspec2
-rw-r--r--actionpack/lib/abstract_controller/translation.rb9
-rw-r--r--actionpack/lib/action_controller/caching.rb4
-rw-r--r--actionpack/lib/action_controller/metal.rb1
-rw-r--r--actionpack/lib/action_controller/metal/conditional_get.rb2
-rw-r--r--actionpack/lib/action_controller/metal/mime_responds.rb1
-rw-r--r--actionpack/lib/action_controller/metal/redirecting.rb2
-rw-r--r--actionpack/lib/action_controller/metal/request_forgery_protection.rb13
-rw-r--r--actionpack/lib/action_controller/metal/strong_parameters.rb120
-rw-r--r--actionpack/lib/action_controller/test_case.rb30
-rw-r--r--actionpack/lib/action_dispatch.rb1
-rw-r--r--actionpack/lib/action_dispatch/http/parameters.rb2
-rw-r--r--actionpack/lib/action_dispatch/http/response.rb16
-rw-r--r--actionpack/lib/action_dispatch/http/upload.rb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/best_standards_support.rb30
-rw-r--r--actionpack/lib/action_dispatch/middleware/cookies.rb17
-rw-r--r--actionpack/lib/action_dispatch/middleware/session/abstract_store.rb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/templates/routes/_route.html.erb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/templates/routes/_table.html.erb108
-rw-r--r--actionpack/lib/action_dispatch/railtie.rb4
-rw-r--r--actionpack/lib/action_dispatch/request/session.rb4
-rw-r--r--actionpack/lib/action_dispatch/routing/inspector.rb23
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb12
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb181
-rw-r--r--actionpack/lib/action_dispatch/routing/routes_proxy.rb2
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helper.rb22
-rw-r--r--actionpack/lib/action_view/helpers/asset_url_helper.rb3
-rw-r--r--actionpack/lib/action_view/helpers/date_helper.rb25
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb9
-rw-r--r--actionpack/lib/action_view/helpers/form_options_helper.rb49
-rw-r--r--actionpack/lib/action_view/helpers/javascript_helper.rb4
-rw-r--r--actionpack/lib/action_view/helpers/record_tag_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/tags/collection_check_boxes.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/collection_radio_buttons.rb4
-rw-r--r--actionpack/lib/action_view/helpers/url_helper.rb2
-rw-r--r--actionpack/lib/action_view/template.rb3
-rw-r--r--actionpack/lib/action_view/template/error.rb2
-rw-r--r--actionpack/lib/action_view/template/handlers/erb.rb2
-rw-r--r--actionpack/lib/action_view/test_case.rb6
-rw-r--r--actionpack/test/abstract/translation_test.rb81
-rw-r--r--actionpack/test/abstract_unit.rb2
-rw-r--r--actionpack/test/activerecord/form_helper_activerecord_test.rb91
-rw-r--r--actionpack/test/controller/integration_test.rb6
-rw-r--r--actionpack/test/controller/layout_test.rb1
-rw-r--r--actionpack/test/controller/localized_templates_test.rb8
-rw-r--r--actionpack/test/controller/parameters/nested_parameters_test.rb62
-rw-r--r--actionpack/test/controller/parameters/parameters_permit_test.rb126
-rw-r--r--actionpack/test/controller/request_forgery_protection_test.rb39
-rw-r--r--actionpack/test/controller/resources_test.rb1
-rw-r--r--actionpack/test/controller/webservice_test.rb13
-rw-r--r--actionpack/test/dispatch/best_standards_support_test.rb35
-rw-r--r--actionpack/test/dispatch/cookies_test.rb50
-rw-r--r--actionpack/test/dispatch/response_test.rb8
-rw-r--r--actionpack/test/dispatch/routing/inspector_test.rb8
-rw-r--r--actionpack/test/dispatch/routing_test.rb70
-rw-r--r--actionpack/test/dispatch/session/cookie_store_test.rb4
-rw-r--r--actionpack/test/dispatch/session/test_session_test.rb16
-rw-r--r--actionpack/test/dispatch/test_request_test.rb6
-rw-r--r--actionpack/test/fixtures/developer.rb1
-rw-r--r--actionpack/test/fixtures/test/_directory/_partial_with_locales.html.erb1
-rw-r--r--actionpack/test/fixtures/test/render_partial_inside_directory.html.erb1
-rw-r--r--actionpack/test/template/asset_tag_helper_test.rb3
-rw-r--r--actionpack/test/template/form_helper_test.rb703
-rw-r--r--actionpack/test/template/javascript_helper_test.rb4
-rw-r--r--actionpack/test/template/record_tag_helper_test.rb6
-rw-r--r--actionpack/test/template/test_case_test.rb21
-rw-r--r--actionpack/test/template/text_helper_test.rb6
-rw-r--r--actionpack/test/template/url_helper_test.rb6
70 files changed, 1592 insertions, 620 deletions
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md
index 2b6425caa5..6940683c8c 100644
--- a/actionpack/CHANGELOG.md
+++ b/actionpack/CHANGELOG.md
@@ -1,9 +1,104 @@
## Rails 4.0.0 (unreleased) ##
-* `BestStandardsSupport` no longer duplicates `X-UA-Compatible` values on
- each request to prevent header size from blowing up.
+* Change `image_alt` method to replace underscores/hyphens to spaces in filenames.
- *Edward Anderson*
+ Previously, underscored filenames became `alt="A_long_file_name_with_underscores"`
+ in HTML, which is poor for accessibility. For instance, Apple's VoiceOver Utility
+ pronounces each underscore. `A_long_file_name` thus would be read as `A underscore
+ long underscore file underscore name.` Now underscored or hyphenated filenames
+ (both of which are very popular naming conventions) read more naturally in
+ screen readers by converting both hyphens and underscores to spaces.
+
+ Before:
+ image_tag('underscored_file_name.png')
+ # => <img alt="Underscored_file_name" src="/assets/underscored_file_name.png" />
+
+ After:
+ image_tag('underscored_file_name.png')
+ # => <img alt="Underscored file name" src="/assets/underscored_file_name.png" />
+
+ *Nick Cox*
+
+* We don't support the `:controller` option for route definitions
+ with the ruby constant notation. This will now result in an
+ `ArgumentError`.
+
+ Example:
+ # This raises an ArgumentError:
+ resources :posts, :controller => "Admin::Posts"
+
+ # Use directory notation instead:
+ resources :posts, :controller => "admin/posts"
+
+ *Yves Senn*
+
+* `assert_template` can be used to verify the locals of partials,
+ which live inside a directory.
+ Fixes #8516.
+
+ # Prefixed partials inside directories worked and still work.
+ assert_template partial: 'directory/_partial', locals: {name: 'John'}
+
+ # This did not work but does now.
+ assert_template partial: 'directory/partial', locals: {name: 'John'}
+
+ *Yves Senn*
+
+* Fix `content_tag_for` with array html option.
+ It would embed array as string instead of joining it like `content_tag` does:
+
+ content_tag(:td, class: ["foo", "bar"]){}
+ #=> '<td class="foo bar"></td>'
+
+ Before:
+
+ content_tag_for(:td, item, class: ["foo", "bar"])
+ #=> '<td class="item [&quot;foo&quot;, &quot;bar&quot;]" id="item_1"></td>'
+
+ After:
+
+ content_tag_for(:td, item, class: ["foo", "bar"])
+ #=> '<td class="item foo bar" id="item_1"></td>'
+
+ *Semyon Perepelitsa*
+
+* Remove `BestStandardsSupport` middleware, !DOCTYPE html already triggers
+ standards mode per http://msdn.microsoft.com/en-us/library/jj676915(v=vs.85).aspx
+ and ChromeFrame header has been moved to `config.action_dispatch.default_headers`
+
+ *Guillermo Iguaran*
+
+* Fix CSRF protection and `current_url?` helper to work with HEAD requests
+ now that `ActionDispatch::Head` has been removed in favor of `Rack::Head`.
+
+ *Michiel Sikkes*
+
+* Change `asset_path` to not include `SCRIPT_NAME` when it's used
+ from a mounted engine. Fixes #8119.
+
+ *Piotr Sarnacki*
+
+* Add javascript based routing path matcher to `/rails/info/routes`.
+ Routes can now be filtered by whether or not they match a path.
+
+ *Richard Schneeman*
+
+* Given
+
+ params.permit(:name)
+
+ `:name` passes if it is a key of `params` whose value is a permitted scalar.
+
+ Similarly, given
+
+ params.permit(tags: [])
+
+ `:tags` passes if it is a key of `params` whose value is an array of
+ permitted scalars.
+
+ Permitted scalars filtering happens at any level of nesting.
+
+ *Xavier Noria*
* Change the behavior of route defaults so that explicit defaults are no longer
required where the key is not part of the path. For example:
@@ -197,7 +292,8 @@
* More descriptive error messages when calling `render :partial` with
an invalid `:layout` argument.
- #8376
+
+ Fixes #8376.
render partial: 'partial', layout: true
@@ -729,7 +825,7 @@
* Removed old text helper apis from `highlight`, `excerpt` and `word_wrap`. *Jeremy Walker*
* Templates without a handler extension now raises a deprecation warning but still
- defaults to ERb. In future releases, it will simply return the template contents. *Steve Klabnik*
+ defaults to ERB. In future releases, it will simply return the template contents. *Steve Klabnik*
* Deprecate `:disable_with` in favor of `data: { disable_with: "Text" }` option from `submit_tag`, `button_tag` and `button_to` helpers.
diff --git a/actionpack/RUNNING_UNIT_TESTS b/actionpack/RUNNING_UNIT_TESTS.rdoc
index 1b29abd2d1..1b29abd2d1 100644
--- a/actionpack/RUNNING_UNIT_TESTS
+++ b/actionpack/RUNNING_UNIT_TESTS.rdoc
diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec
index f00fc46b2e..008f17bceb 100644
--- a/actionpack/actionpack.gemspec
+++ b/actionpack/actionpack.gemspec
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
s.add_dependency 'activesupport', version
s.add_dependency 'builder', '~> 3.1.0'
- s.add_dependency 'rack', '~> 1.4.3'
+ s.add_dependency 'rack', '~> 1.5.2'
s.add_dependency 'rack-test', '~> 0.6.1'
s.add_dependency 'erubis', '~> 2.7.0'
diff --git a/actionpack/lib/abstract_controller/translation.rb b/actionpack/lib/abstract_controller/translation.rb
index b6c484d188..db48022b9f 100644
--- a/actionpack/lib/abstract_controller/translation.rb
+++ b/actionpack/lib/abstract_controller/translation.rb
@@ -1,5 +1,13 @@
module AbstractController
module Translation
+ # Delegates to <tt>I18n.translate</tt>. Also aliased as <tt>t</tt>.
+ #
+ # When the given key starts with a period, it will be scoped by the current
+ # controller and action. So if you call <tt>translate(".foo")</tt> from
+ # <tt>PeopleController#index</tt>, it will convert the call to
+ # <tt>I18n.translate("people.index.foo")</tt>. This makes it less repetitive
+ # to translate many keys within the same controller / action and gives you a
+ # simple framework for scoping them consistently.
def translate(*args)
key = args.first
if key.is_a?(String) && (key[0] == '.')
@@ -11,6 +19,7 @@ module AbstractController
end
alias :t :translate
+ # Delegates to <tt>I18n.localize</tt>. Also aliased as <tt>l</tt>.
def localize(*args)
I18n.localize(*args)
end
diff --git a/actionpack/lib/action_controller/caching.rb b/actionpack/lib/action_controller/caching.rb
index cf2cda039d..ea33d975ef 100644
--- a/actionpack/lib/action_controller/caching.rb
+++ b/actionpack/lib/action_controller/caching.rb
@@ -82,10 +82,6 @@ module ActionController
end
end
- def caching_allowed?
- request.get? && response.status == 200
- end
-
def view_cache_dependencies
self.class._view_cache_dependencies.map { |dep| instance_exec(&dep) }.compact
end
diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb
index 832dec7b2a..143b3e0cbd 100644
--- a/actionpack/lib/action_controller/metal.rb
+++ b/actionpack/lib/action_controller/metal.rb
@@ -1,3 +1,4 @@
+require 'active_support/core_ext/array/extract_options'
require 'action_dispatch/middleware/stack'
module ActionController
diff --git a/actionpack/lib/action_controller/metal/conditional_get.rb b/actionpack/lib/action_controller/metal/conditional_get.rb
index eddee08545..6e0cd51d8b 100644
--- a/actionpack/lib/action_controller/metal/conditional_get.rb
+++ b/actionpack/lib/action_controller/metal/conditional_get.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/hash/keys'
+
module ActionController
module ConditionalGet
extend ActiveSupport::Concern
diff --git a/actionpack/lib/action_controller/metal/mime_responds.rb b/actionpack/lib/action_controller/metal/mime_responds.rb
index d04fbae150..93568da9ef 100644
--- a/actionpack/lib/action_controller/metal/mime_responds.rb
+++ b/actionpack/lib/action_controller/metal/mime_responds.rb
@@ -1,3 +1,4 @@
+require 'active_support/core_ext/array/extract_options'
require 'abstract_controller/collector'
module ActionController #:nodoc:
diff --git a/actionpack/lib/action_controller/metal/redirecting.rb b/actionpack/lib/action_controller/metal/redirecting.rb
index 59b91a240e..e9031f3fac 100644
--- a/actionpack/lib/action_controller/metal/redirecting.rb
+++ b/actionpack/lib/action_controller/metal/redirecting.rb
@@ -88,7 +88,7 @@ module ActionController
# letters, digits, and the plus ("+"), period ("."), or hyphen ("-")
# characters; and is terminated by a colon (":").
# The protocol relative scheme starts with a double slash "//"
- when %r{^(\w[\w+.-]*:|//).*}
+ when %r{\A(\w[\w+.-]*:|//).*}
options
when String
request.protocol + request.host_with_port + options
diff --git a/actionpack/lib/action_controller/metal/request_forgery_protection.rb b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
index c5db0cb0d4..17379cf7ac 100644
--- a/actionpack/lib/action_controller/metal/request_forgery_protection.rb
+++ b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
@@ -102,15 +102,16 @@ module ActionController #:nodoc:
# This is the method that defines the application behavior when a request is found to be unverified.
def handle_unverified_request
- request.session = NullSessionHash.new
+ request.session = NullSessionHash.new(request.env)
request.env['action_dispatch.request.flash_hash'] = nil
request.env['rack.session.options'] = { skip: true }
request.env['action_dispatch.cookies'] = NullCookieJar.build(request)
end
class NullSessionHash < Rack::Session::Abstract::SessionHash #:nodoc:
- def initialize
- super(nil, nil)
+ def initialize(env)
+ super(nil, env)
+ @data = {}
@loaded = true
end
@@ -125,7 +126,7 @@ module ActionController #:nodoc:
host = request.host
secure = request.ssl?
- new(key_generator, host, secure)
+ new(key_generator, host, secure, options_for_env({}))
end
def write(*)
@@ -162,11 +163,11 @@ module ActionController #:nodoc:
# Returns true or false if a request is verified. Checks:
#
- # * is it a GET request? Gets should be safe and idempotent
+ # * is it a GET or HEAD request? Gets should be safe and idempotent
# * Does the form_authenticity_token match the given token value from the params?
# * Does the X-CSRF-Token header match the form_authenticity_token
def verified_request?
- !protect_against_forgery? || request.get? ||
+ !protect_against_forgery? || request.get? || request.head? ||
form_authenticity_token == params[request_forgery_protection_token] ||
form_authenticity_token == request.headers['X-CSRF-Token']
end
diff --git a/actionpack/lib/action_controller/metal/strong_parameters.rb b/actionpack/lib/action_controller/metal/strong_parameters.rb
index 2c96e03f55..7e720ca6f5 100644
--- a/actionpack/lib/action_controller/metal/strong_parameters.rb
+++ b/actionpack/lib/action_controller/metal/strong_parameters.rb
@@ -1,6 +1,7 @@
require 'active_support/core_ext/hash/indifferent_access'
require 'active_support/core_ext/array/wrap'
require 'active_support/rescuable'
+require 'action_dispatch/http/upload'
module ActionController
# Raised when a required parameter is missing.
@@ -184,6 +185,21 @@ module ActionController
# permitted.has_key?(:age) # => true
# permitted.has_key?(:role) # => false
#
+ # Only permitted scalars pass the filter. For example, given
+ #
+ # params.permit(:name)
+ #
+ # +:name+ passes it is a key of +params+ whose associated value is of type
+ # +String+, +Symbol+, +NilClass+, +Numeric+, +TrueClass+, +FalseClass+,
+ # +Date+, +Time+, +DateTime+, +StringIO+, +IO+, or
+ # +ActionDispatch::Http::UploadedFile+. Otherwise, the key +:name+ is
+ # filtered out.
+ #
+ # You may declare that the parameter should be an array of permitted scalars
+ # by mapping it to an empty array:
+ #
+ # params.permit(tags: [])
+ #
# You can also use +permit+ on nested parameters, like:
#
# params = ActionController::Parameters.new({
@@ -230,33 +246,14 @@ module ActionController
filters.flatten.each do |filter|
case filter
- when Symbol, String then
- if has_key?(filter)
- _value = self[filter]
- params[filter] = _value unless Hash === _value
- end
- keys.grep(/\A#{Regexp.escape(filter)}\(\d+[if]?\)\z/) { |key| params[key] = self[key] }
+ when Symbol, String
+ permitted_scalar_filter(params, filter)
when Hash then
- filter = filter.with_indifferent_access
-
- self.slice(*filter.keys).each do |key, values|
- return unless values
-
- key = key.to_sym
-
- params[key] = each_element(values) do |value|
- # filters are a Hash, so we expect value to be a Hash too
- next if filter.is_a?(Hash) && !value.is_a?(Hash)
-
- value = self.class.new(value) if !value.respond_to?(:permit)
-
- value.permit(*Array.wrap(filter[key]))
- end
- end
+ hash_filter(params, filter)
end
end
- unpermitted_parameters!(params)
+ unpermitted_parameters!(params) if self.class.action_on_unpermitted_parameters
params.permit!
end
@@ -352,6 +349,83 @@ module ActionController
def unpermitted_keys(params)
self.keys - params.keys - NEVER_UNPERMITTED_PARAMS
end
+
+ #
+ # --- Filtering ----------------------------------------------------------
+ #
+
+ # This is a white list of permitted scalar types that includes the ones
+ # supported in XML and JSON requests.
+ #
+ # This list is in particular used to filter ordinary requests, String goes
+ # as first element to quickly short-circuit the common case.
+ #
+ # If you modify this collection please update the API of +permit+ above.
+ PERMITTED_SCALAR_TYPES = [
+ String,
+ Symbol,
+ NilClass,
+ Numeric,
+ TrueClass,
+ FalseClass,
+ Date,
+ Time,
+ # DateTimes are Dates, we document the type but avoid the redundant check.
+ StringIO,
+ IO,
+ ActionDispatch::Http::UploadedFile,
+ ]
+
+ def permitted_scalar?(value)
+ PERMITTED_SCALAR_TYPES.any? {|type| value.is_a?(type)}
+ end
+
+ def permitted_scalar_filter(params, key)
+ if has_key?(key) && permitted_scalar?(self[key])
+ params[key] = self[key]
+ end
+
+ keys.grep(/\A#{Regexp.escape(key)}\(\d+[if]?\)\z/) do |k|
+ if permitted_scalar?(self[k])
+ params[k] = self[k]
+ end
+ end
+ end
+
+ def array_of_permitted_scalars?(value)
+ if value.is_a?(Array)
+ value.all? {|element| permitted_scalar?(element)}
+ end
+ end
+
+ def array_of_permitted_scalars_filter(params, key)
+ if has_key?(key) && array_of_permitted_scalars?(self[key])
+ params[key] = self[key]
+ end
+ end
+
+ EMPTY_ARRAY = []
+ def hash_filter(params, filter)
+ filter = filter.with_indifferent_access
+
+ # Slicing filters out non-declared keys.
+ slice(*filter.keys).each do |key, value|
+ return unless value
+
+ if filter[key] == EMPTY_ARRAY
+ # Declaration { comment_ids: [] }.
+ array_of_permitted_scalars_filter(params, key)
+ else
+ # Declaration { user: :name } or { user: [:name, :age, { adress: ... }] }.
+ params[key] = each_element(value) do |element|
+ if element.is_a?(Hash)
+ element = self.class.new(element) unless element.respond_to?(:permit)
+ element.permit(*Array.wrap(filter[key]))
+ end
+ end
+ end
+ end
+ end
end
# == Strong \Parameters
diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb
index d8206b573d..bba1f1e201 100644
--- a/actionpack/lib/action_controller/test_case.rb
+++ b/actionpack/lib/action_controller/test_case.rb
@@ -1,6 +1,7 @@
require 'rack/session/abstract/id'
require 'active_support/core_ext/object/to_query'
require 'active_support/core_ext/module/anonymous'
+require 'active_support/core_ext/hash/keys'
module ActionController
module TemplateAssertions
@@ -125,7 +126,11 @@ module ActionController
if expected_partial = options[:partial]
if expected_locals = options[:locals]
if defined?(@_rendered_views)
- view = expected_partial.to_s.sub(/^_/,'')
+ view = expected_partial.to_s.sub(/^_/, '').sub(/\/_(?=[^\/]+\z)/, '/')
+
+ partial_was_not_rendered_msg = "expected %s to be rendered but it was not." % view
+ assert_includes @_rendered_views.rendered_views, view, partial_was_not_rendered_msg
+
msg = 'expecting %s to be rendered with %s but was with %s' % [expected_partial,
expected_locals,
@_rendered_views.locals_for(view)]
@@ -235,18 +240,39 @@ module ActionController
end
end
+ # Methods #destroy and #load! are overridden to avoid calling methods on the
+ # @store object, which does not exist for the TestSession class.
class TestSession < Rack::Session::Abstract::SessionHash #:nodoc:
DEFAULT_OPTIONS = Rack::Session::Abstract::ID::DEFAULT_OPTIONS
def initialize(session = {})
super(nil, nil)
- replace(session.stringify_keys)
+ @id = SecureRandom.hex(16)
+ @data = stringify_keys(session)
@loaded = true
end
def exists?
true
end
+
+ def keys
+ @data.keys
+ end
+
+ def values
+ @data.values
+ end
+
+ def destroy
+ clear
+ end
+
+ private
+
+ def load!
+ @id
+ end
end
# Superclass for ActionController functional tests. Functional tests allow you to
diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb
index 9ab048b756..618e2f3033 100644
--- a/actionpack/lib/action_dispatch.rb
+++ b/actionpack/lib/action_dispatch.rb
@@ -47,7 +47,6 @@ module ActionDispatch
autoload_under 'middleware' do
autoload :RequestId
- autoload :BestStandardsSupport
autoload :Callbacks
autoload :Cookies
autoload :DebugExceptions
diff --git a/actionpack/lib/action_dispatch/http/parameters.rb b/actionpack/lib/action_dispatch/http/parameters.rb
index 25edd196c3..446862aad0 100644
--- a/actionpack/lib/action_dispatch/http/parameters.rb
+++ b/actionpack/lib/action_dispatch/http/parameters.rb
@@ -55,7 +55,7 @@ module ActionDispatch
# should really prevent that from happening
def encode_params(params)
if params.is_a?(String)
- return params.force_encoding("UTF-8").encode!
+ return params.force_encoding(Encoding::UTF_8).encode!
elsif !params.is_a?(Hash)
return params
end
diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb
index 91cf4784db..e7e8905d7e 100644
--- a/actionpack/lib/action_dispatch/http/response.rb
+++ b/actionpack/lib/action_dispatch/http/response.rb
@@ -137,6 +137,7 @@ module ActionDispatch # :nodoc:
@committed
end
+ # Sets the HTTP status code.
def status=(status)
@status = Rack::Utils.status_code(status)
end
@@ -145,16 +146,24 @@ module ActionDispatch # :nodoc:
@content_type = content_type.to_s
end
- # The response code of the request
+ # The response code of the request.
def response_code
@status
end
- # Returns a String to ensure compatibility with Net::HTTPResponse
+ # Returns a string to ensure compatibility with <tt>Net::HTTPResponse</tt>.
def code
@status.to_s
end
+ # Returns the corresponding message for the current HTTP status code:
+ #
+ # response.status = 200
+ # response.message # => "OK"
+ #
+ # response.status = 404
+ # response.message # => "Not Found"
+ #
def message
Rack::Utils::HTTP_STATUS_CODES[@status]
end
@@ -172,6 +181,8 @@ module ActionDispatch # :nodoc:
stream.to_path
end
+ # Returns the content of the response as a string. This contains the contents
+ # of any calls to <tt>render</tt>.
def body
strings = []
each { |part| strings << part.to_s }
@@ -180,6 +191,7 @@ module ActionDispatch # :nodoc:
EMPTY = " "
+ # Allows you to manually set or override the response body.
def body=(body)
@blank = true if body == EMPTY
diff --git a/actionpack/lib/action_dispatch/http/upload.rb b/actionpack/lib/action_dispatch/http/upload.rb
index 8a97248eb3..67cb7fbcb5 100644
--- a/actionpack/lib/action_dispatch/http/upload.rb
+++ b/actionpack/lib/action_dispatch/http/upload.rb
@@ -70,7 +70,7 @@ module ActionDispatch
def encode_filename(filename)
# Encode the filename in the utf8 encoding, unless it is nil
- filename.force_encoding("UTF-8").encode! if filename
+ filename.force_encoding(Encoding::UTF_8).encode! if filename
end
end
diff --git a/actionpack/lib/action_dispatch/middleware/best_standards_support.rb b/actionpack/lib/action_dispatch/middleware/best_standards_support.rb
deleted file mode 100644
index 94efeb79fa..0000000000
--- a/actionpack/lib/action_dispatch/middleware/best_standards_support.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-module ActionDispatch
- class BestStandardsSupport
- def initialize(app, type = true)
- @app = app
-
- @header = case type
- when true
- "IE=Edge,chrome=1"
- when :builtin
- "IE=Edge"
- when false
- nil
- end
- end
-
- def call(env)
- status, headers, body = @app.call(env)
-
- if headers["X-UA-Compatible"] && @header
- unless headers["X-UA-Compatible"][@header]
- headers["X-UA-Compatible"] << "," << @header.to_s
- end
- else
- headers["X-UA-Compatible"] = @header
- end
-
- [status, headers, body]
- end
- end
-end
diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb
index 6ecbb03784..fff26bd1b2 100644
--- a/actionpack/lib/action_dispatch/middleware/cookies.rb
+++ b/actionpack/lib/action_dispatch/middleware/cookies.rb
@@ -1,5 +1,6 @@
require 'active_support/core_ext/hash/keys'
require 'active_support/core_ext/module/attribute_accessors'
+require 'active_support/key_generator'
require 'active_support/message_verifier'
module ActionDispatch
@@ -110,13 +111,17 @@ module ActionDispatch
# $& => example.local
DOMAIN_REGEXP = /[^.]*\.([^.]*|..\...|...\...)$/
+ def self.options_for_env(env) #:nodoc:
+ { signed_cookie_salt: env[SIGNED_COOKIE_SALT] || '',
+ encrypted_cookie_salt: env[ENCRYPTED_COOKIE_SALT] || '',
+ encrypted_signed_cookie_salt: env[ENCRYPTED_SIGNED_COOKIE_SALT] || '',
+ token_key: env[TOKEN_KEY] }
+ end
+
def self.build(request)
env = request.env
key_generator = env[GENERATOR_KEY]
- options = { signed_cookie_salt: env[SIGNED_COOKIE_SALT],
- encrypted_cookie_salt: env[ENCRYPTED_COOKIE_SALT],
- encrypted_signed_cookie_salt: env[ENCRYPTED_SIGNED_COOKIE_SALT],
- token_key: env[TOKEN_KEY] }
+ options = options_for_env env
host = request.host
secure = request.ssl?
@@ -145,6 +150,10 @@ module ActionDispatch
@cookies[name.to_s]
end
+ def fetch(name, *args, &block)
+ @cookies.fetch(name.to_s, *args, &block)
+ end
+
def key?(name)
@cookies.key?(name.to_s)
end
diff --git a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
index 7c12590c49..84df55fd5a 100644
--- a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
+++ b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
@@ -26,7 +26,7 @@ module ActionDispatch
def generate_sid
sid = SecureRandom.hex(16)
- sid.encode!('UTF-8')
+ sid.encode!(Encoding::UTF_8)
sid
end
diff --git a/actionpack/lib/action_dispatch/middleware/templates/routes/_route.html.erb b/actionpack/lib/action_dispatch/middleware/templates/routes/_route.html.erb
index 400ae97d22..24e44f31ac 100644
--- a/actionpack/lib/action_dispatch/middleware/templates/routes/_route.html.erb
+++ b/actionpack/lib/action_dispatch/middleware/templates/routes/_route.html.erb
@@ -7,7 +7,7 @@
<td data-route-verb='<%= route[:verb] %>'>
<%= route[:verb] %>
</td>
- <td data-route-path='<%= route[:path] %>'>
+ <td data-route-path='<%= route[:path] %>' data-regexp='<%= route[:regexp] %>'>
<%= route[:path] %>
</td>
<td data-route-reqs='<%= route[:reqs] %>'>
diff --git a/actionpack/lib/action_dispatch/middleware/templates/routes/_table.html.erb b/actionpack/lib/action_dispatch/middleware/templates/routes/_table.html.erb
index 9026c4eeb2..95461fa693 100644
--- a/actionpack/lib/action_dispatch/middleware/templates/routes/_table.html.erb
+++ b/actionpack/lib/action_dispatch/middleware/templates/routes/_table.html.erb
@@ -1,22 +1,58 @@
<% content_for :style do %>
- #route_table td { padding: 0 30px; }
- #route_table { margin: 0 auto 0; }
+ #route_table {
+ margin: 0 auto 0;
+ border-collapse: collapse;
+ }
+
+ #route_table td {
+ padding: 0 30px;
+ }
+
+ #route_table tr.bottom th {
+ padding-bottom: 10px;
+ line-height: 15px;
+ }
+
+ #route_table .matched_paths {
+ background-color: LightGoldenRodYellow;
+ }
+
+ #route_table .matched_paths {
+ border-bottom: solid 3px SlateGrey;
+ }
+
+ #path_search {
+ width: 80%;
+ font-size: inherit;
+ }
<% end %>
<table id='route_table' class='route_table'>
<thead>
<tr>
- <th>Helper<br />
+ <th>Helper</th>
+ <th>HTTP Verb</th>
+ <th>Path</th>
+ <th>Controller#Action</th>
+ </tr>
+ <tr class='bottom'>
+ <th><%# Helper %>
<%= link_to "Path", "#", 'data-route-helper' => '_path',
title: "Returns a relative path (without the http or domain)" %> /
<%= link_to "Url", "#", 'data-route-helper' => '_url',
- title: "Returns an absolute url (with the http and domain)" %>
+ title: "Returns an absolute url (with the http and domain)" %>
+ </th>
+ <th><%# HTTP Verb %>
+ </th>
+ <th><%# Path %>
+ <%= search_field(:path, nil, id: 'path_search', placeholder: "Path Match") %>
+ </th>
+ <th><%# Controller#action %>
</th>
- <th>HTTP Verb</th>
- <th>Path</th>
- <th>Controller#Action</th>
</tr>
</thead>
+ <tbody class='matched_paths' id='matched_paths'>
+ </tbody>
<tbody>
<%= yield %>
</tbody>
@@ -25,7 +61,7 @@
<script type='text/javascript'>
function each(elems, func) {
if (!elems instanceof Array) { elems = [elems]; }
- for (var i = elems.length; i--; ) {
+ for (var i = 0, len = elems.length; i < len; i++) {
func(elems[i]);
}
}
@@ -46,11 +82,63 @@
function setupRouteToggleHelperLinks() {
var toggleLinks = document.querySelectorAll('#route_table [data-route-helper]');
onClick(toggleLinks, function(){
- var helperTxt = this.getAttribute("data-route-helper");
- var helperElems = document.querySelectorAll('[data-route-name] span.helper');
+ var helperTxt = this.getAttribute("data-route-helper"),
+ helperElems = document.querySelectorAll('[data-route-name] span.helper');
setValOn(helperElems, helperTxt);
});
}
+ // takes an array of elements with a data-regexp attribute and
+ // passes their their parent <tr> into the callback function
+ // if the regexp matchs a given path
+ function eachElemsForPath(elems, path, func) {
+ each(elems, function(e){
+ var reg = e.getAttribute("data-regexp");
+ if (path.match(RegExp(reg))) {
+ func(e.parentNode.cloneNode(true));
+ }
+ })
+ }
+
+ // Ensure path always starts with a slash "/" and remove params or fragments
+ function sanitizePath(path) {
+ var path = path.charAt(0) == '/' ? path : "/" + path;
+ return path.replace(/\#.*|\?.*/, '');
+ }
+
+ // Enables path search functionality
+ function setupMatchPaths() {
+ var regexpElems = document.querySelectorAll('#route_table [data-regexp]'),
+ pathElem = document.querySelector('#path_search'),
+ selectedSection = document.querySelector('#matched_paths'),
+ noMatchText = '<tr><th colspan="4">None</th></tr>';
+
+
+ // Remove matches if no path is present
+ pathElem.onblur = function(e) {
+ if (pathElem.value === "") selectedSection.innerHTML = "";
+ }
+
+ // On key press perform a search for matching paths
+ pathElem.onkeyup = function(e){
+ var path = sanitizePath(pathElem.value),
+ defaultText = '<tr><th colspan="4">Paths Matching (' + path + '):</th></tr>';
+
+ // Clear out results section
+ selectedSection.innerHTML= defaultText;
+
+ // Display matches if they exist
+ eachElemsForPath(regexpElems, path, function(e){
+ selectedSection.appendChild(e);
+ });
+
+ // If no match present, tell the user
+ if (selectedSection.innerHTML === defaultText) {
+ selectedSection.innerHTML = selectedSection.innerHTML + noMatchText;
+ }
+ }
+ }
+
+ setupMatchPaths();
setupRouteToggleHelperLinks();
</script>
diff --git a/actionpack/lib/action_dispatch/railtie.rb b/actionpack/lib/action_dispatch/railtie.rb
index 5a835ae439..edf37bb9a5 100644
--- a/actionpack/lib/action_dispatch/railtie.rb
+++ b/actionpack/lib/action_dispatch/railtie.rb
@@ -6,7 +6,6 @@ module ActionDispatch
config.action_dispatch.x_sendfile_header = nil
config.action_dispatch.ip_spoofing_check = true
config.action_dispatch.show_exceptions = true
- config.action_dispatch.best_standards_support = true
config.action_dispatch.tld_length = 1
config.action_dispatch.ignore_accept_header = false
config.action_dispatch.rescue_templates = { }
@@ -21,7 +20,8 @@ module ActionDispatch
config.action_dispatch.default_headers = {
'X-Frame-Options' => 'SAMEORIGIN',
'X-XSS-Protection' => '1; mode=block',
- 'X-Content-Type-Options' => 'nosniff'
+ 'X-Content-Type-Options' => 'nosniff',
+ 'X-UA-Compatible' => 'chrome=1'
}
config.eager_load_namespaces << ActionDispatch
diff --git a/actionpack/lib/action_dispatch/request/session.rb b/actionpack/lib/action_dispatch/request/session.rb
index a05a23d953..7bc812fd22 100644
--- a/actionpack/lib/action_dispatch/request/session.rb
+++ b/actionpack/lib/action_dispatch/request/session.rb
@@ -63,6 +63,10 @@ module ActionDispatch
@exists = nil # we haven't checked yet
end
+ def id
+ options[:id]
+ end
+
def options
Options.find @env
end
diff --git a/actionpack/lib/action_dispatch/routing/inspector.rb b/actionpack/lib/action_dispatch/routing/inspector.rb
index 6c970f3024..bc6dd7145c 100644
--- a/actionpack/lib/action_dispatch/routing/inspector.rb
+++ b/actionpack/lib/action_dispatch/routing/inspector.rb
@@ -34,6 +34,23 @@ module ActionDispatch
super.to_s
end
+ def regexp
+ __getobj__.path.to_regexp
+ end
+
+ def json_regexp
+ str = regexp.inspect.
+ sub('\\A' , '^').
+ sub('\\Z' , '$').
+ sub('\\z' , '$').
+ sub(/^\// , '').
+ sub(/\/[a-z]*$/ , '').
+ gsub(/\(\?#.+\)/ , '').
+ gsub(/\(\?-\w+:/ , '(').
+ gsub(/\s/ , '')
+ Regexp.new(str).source
+ end
+
def reqs
@reqs ||= begin
reqs = endpoint
@@ -101,7 +118,11 @@ module ActionDispatch
end.collect do |route|
collect_engine_routes(route)
- { name: route.name, verb: route.verb, path: route.path, reqs: route.reqs }
+ { name: route.name,
+ verb: route.verb,
+ path: route.path,
+ reqs: route.reqs,
+ regexp: route.json_regexp }
end
end
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index 6d93f609a6..0a41ed0fcf 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -2,6 +2,7 @@ require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/hash/reverse_merge'
require 'active_support/core_ext/hash/slice'
require 'active_support/core_ext/enumerable'
+require 'active_support/core_ext/array/extract_options'
require 'active_support/inflector'
require 'action_dispatch/routing/redirection'
@@ -245,6 +246,12 @@ module ActionDispatch
raise ArgumentError, "missing :action"
end
+ if controller.is_a?(String) && controller !~ /\A[a-z_0-9\/]*\z/
+ message = "'#{controller}' is not a supported controller name. This can lead to potential routing problems."
+ message << " See http://guides.rubyonrails.org/routing.html#specifying-a-controller-to-use"
+ raise ArgumentError, message
+ end
+
hash = {}
hash[:controller] = controller unless controller.blank?
hash[:action] = action unless action.blank?
@@ -1403,9 +1410,10 @@ module ActionDispatch
def add_route(action, options) # :nodoc:
path = path_for_action(action, options.delete(:path))
+ action = action.to_s.dup
- if action.to_s =~ /^[\w\/]+$/
- options[:action] ||= action unless action.to_s.include?("/")
+ if action =~ /^[\w\/]+$/
+ options[:action] ||= action unless action.include?("/")
else
action = nil
end
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index c72310cca3..ff86f87d49 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -4,6 +4,7 @@ require 'thread_safe'
require 'active_support/core_ext/object/to_query'
require 'active_support/core_ext/hash/slice'
require 'active_support/core_ext/module/remove_method'
+require 'active_support/core_ext/array/extract_options'
require 'action_controller/metal/exceptions'
module ActionDispatch
@@ -100,36 +101,16 @@ module ActionDispatch
def initialize
@routes = {}
@helpers = []
- @module = Module.new do
- protected
-
- def handle_positional_args(args, options, segment_keys)
- inner_options = args.extract_options!
- result = options.dup
-
- if args.size > 0
- keys = segment_keys
- if args.size < keys.size - 1 # take format into account
- keys -= self.url_options.keys if self.respond_to?(:url_options)
- keys -= options.keys
- end
- result.merge!(Hash[keys.zip(args)])
- end
-
- result.merge!(inner_options)
- end
- end
+ @module = Module.new
end
def helper_names
- self.module.instance_methods.map(&:to_s)
+ @helpers.map(&:to_s)
end
def clear!
@helpers.each do |helper|
- @module.module_eval do
- remove_possible_method helper
- end
+ @module.remove_possible_method helper
end
@routes.clear
@@ -162,68 +143,126 @@ module ActionDispatch
routes.length
end
- private
+ class UrlHelper # :nodoc:
+ def self.create(route, options)
+ if optimize_helper?(route)
+ OptimizedUrlHelper.new(route, options)
+ else
+ new route, options
+ end
+ end
- def define_named_route_methods(name, route)
- define_url_helper route, :"#{name}_path",
- route.defaults.merge(:use_route => name, :only_path => true)
- define_url_helper route, :"#{name}_url",
- route.defaults.merge(:use_route => name, :only_path => false)
+ def self.optimize_helper?(route)
+ route.requirements.except(:controller, :action).empty?
end
- # Create a url helper allowing ordered parameters to be associated
- # with corresponding dynamic segments, so you can do:
- #
- # foo_url(bar, baz, bang)
- #
- # Instead of:
- #
- # foo_url(bar: bar, baz: baz, bang: bang)
- #
- # Also allow options hash, so you can do:
- #
- # foo_url(bar, baz, bang, sort_by: 'baz')
- #
- def define_url_helper(route, name, options)
- @module.module_eval <<-END_EVAL, __FILE__, __LINE__ + 1
- remove_possible_method :#{name}
- def #{name}(*args)
- if #{optimize_helper?(route)} && args.size == #{route.required_parts.size} && !args.last.is_a?(Hash) && optimize_routes_generation?
- options = #{options.inspect}
- options.merge!(url_options) if respond_to?(:url_options)
- options[:path] = "#{optimized_helper(route)}"
- ActionDispatch::Http::URL.url_for(options)
- else
- url_for(handle_positional_args(args, #{options.inspect}, #{route.segment_keys.inspect}))
- end
+ class OptimizedUrlHelper < UrlHelper # :nodoc:
+ attr_reader :arg_size
+
+ def initialize(route, options)
+ super
+ @path_parts = @route.required_parts
+ @arg_size = @path_parts.size
+ @string_route = string_route(route)
+ end
+
+ def call(t, args)
+ if args.size == arg_size && !args.last.is_a?(Hash) && optimize_routes_generation?(t)
+ @options.merge!(t.url_options) if t.respond_to?(:url_options)
+ @options[:path] = optimized_helper(args)
+ ActionDispatch::Http::URL.url_for(@options)
+ else
+ super
end
- END_EVAL
+ end
+
+ private
+
+ def string_route(route)
+ string_route = route.ast.to_s.dup
+ while string_route.gsub!(/\([^\)]*\)/, "")
+ true
+ end
+ string_route
+ end
+
+ def optimized_helper(args)
+ path = @string_route.dup
+ klass = Journey::Router::Utils
- helpers << name
+ @path_parts.zip(args) do |part, arg|
+ # Replace each route parameter
+ # e.g. :id for regular parameter or *path for globbing
+ # with ruby string interpolation code
+ path.gsub!(/(\*|:)#{part}/, klass.escape_fragment(arg.to_param))
+ end
+ path
+ end
+
+ def optimize_routes_generation?(t)
+ t.send(:optimize_routes_generation?)
+ end
end
- # Clause check about when we need to generate an optimized helper.
- def optimize_helper?(route) #:nodoc:
- route.requirements.except(:controller, :action).empty?
+ def initialize(route, options)
+ @options = options
+ @segment_keys = route.segment_keys
+ @route = route
+ end
+
+ def call(t, args)
+ t.url_for(handle_positional_args(t, args, @options, @segment_keys))
end
- # Generates the interpolation to be used in the optimized helper.
- def optimized_helper(route)
- string_route = route.ast.to_s
+ def handle_positional_args(t, args, options, keys)
+ inner_options = args.extract_options!
+ result = options.dup
- while string_route.gsub!(/\([^\)]*\)/, "")
- true
+ if args.size > 0
+ if args.size < keys.size - 1 # take format into account
+ keys -= t.url_options.keys if t.respond_to?(:url_options)
+ keys -= options.keys
+ end
+ result.merge!(Hash[keys.zip(args)])
end
- route.required_parts.each_with_index do |part, i|
- # Replace each route parameter
- # e.g. :id for regular parameter or *path for globbing
- # with ruby string interpolation code
- string_route.gsub!(/(\*|:)#{part}/, "\#{Journey::Router::Utils.escape_fragment(args[#{i}].to_param)}")
- end
+ result.merge!(inner_options)
+ end
+ end
+
+ private
+ # Create a url helper allowing ordered parameters to be associated
+ # with corresponding dynamic segments, so you can do:
+ #
+ # foo_url(bar, baz, bang)
+ #
+ # Instead of:
+ #
+ # foo_url(bar: bar, baz: baz, bang: bang)
+ #
+ # Also allow options hash, so you can do:
+ #
+ # foo_url(bar, baz, bang, sort_by: 'baz')
+ #
+ def define_url_helper(route, name, options)
+ helper = UrlHelper.create(route, options.dup)
- string_route
+ @module.remove_possible_method name
+ @module.module_eval do
+ define_method(name) do |*args|
+ helper.call self, args
+ end
end
+
+ helpers << name
+ end
+
+ def define_named_route_methods(name, route)
+ define_url_helper route, :"#{name}_path",
+ route.defaults.merge(:use_route => name, :only_path => true)
+ define_url_helper route, :"#{name}_url",
+ route.defaults.merge(:use_route => name, :only_path => false)
+ end
end
attr_accessor :formatter, :set, :named_routes, :default_scope, :router
diff --git a/actionpack/lib/action_dispatch/routing/routes_proxy.rb b/actionpack/lib/action_dispatch/routing/routes_proxy.rb
index 73af5920ed..e2393d3799 100644
--- a/actionpack/lib/action_dispatch/routing/routes_proxy.rb
+++ b/actionpack/lib/action_dispatch/routing/routes_proxy.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/array/extract_options'
+
module ActionDispatch
module Routing
class RoutesProxy #:nodoc:
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
index 11743e36f2..31e37893c6 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -182,6 +182,8 @@ module ActionView
# width="30" and height="45", and "50" becomes width="50" and height="50".
# <tt>:size</tt> will be ignored if the value is not in the correct format.
#
+ # ==== Examples
+ #
# image_tag("icon")
# # => <img alt="Icon" src="/assets/icon" />
# image_tag("icon.png")
@@ -212,10 +214,24 @@ module ActionView
end
# Returns a string suitable for an html image tag alt attribute.
- # +src+ is meant to be an image file path.
- # It removes the basename of the file path and the digest, if any.
+ # The +src+ argument is meant to be an image file path.
+ # The method removes the basename of the file path and the digest,
+ # if any. It also removes hyphens and underscores from file names and
+ # replaces them with spaces, returning a space-separated, titleized
+ # string.
+ #
+ # ==== Examples
+ #
+ # image_tag('rails.png')
+ # # => <img alt="Rails" src="/assets/rails.png" />
+ #
+ # image_tag('hyphenated-file-name.png')
+ # # => <img alt="Hyphenated file name" src="/assets/hyphenated-file-name.png" />
+ #
+ # image_tag('underscored_file_name.png')
+ # # => <img alt="Underscored file name" src="/assets/underscored_file_name.png" />
def image_alt(src)
- File.basename(src, '.*').sub(/-[[:xdigit:]]{32}\z/, '').capitalize
+ File.basename(src, '.*').sub(/-[[:xdigit:]]{32}\z/, '').tr('-_', ' ').capitalize
end
# Returns an html video tag for the +sources+. If +sources+ is a string,
diff --git a/actionpack/lib/action_view/helpers/asset_url_helper.rb b/actionpack/lib/action_view/helpers/asset_url_helper.rb
index 0affac41e8..71b78cf0b5 100644
--- a/actionpack/lib/action_view/helpers/asset_url_helper.rb
+++ b/actionpack/lib/action_view/helpers/asset_url_helper.rb
@@ -132,8 +132,7 @@ module ActionView
source = compute_asset_path(source, options)
end
- relative_url_root = (defined?(config.relative_url_root) && config.relative_url_root) ||
- (respond_to?(:request) && request.try(:script_name))
+ relative_url_root = defined?(config.relative_url_root) && config.relative_url_root
if relative_url_root
source = "#{relative_url_root}#{source}" unless source.starts_with?("#{relative_url_root}/")
end
diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb
index 10748aacf4..61f939bff1 100644
--- a/actionpack/lib/action_view/helpers/date_helper.rb
+++ b/actionpack/lib/action_view/helpers/date_helper.rb
@@ -1,5 +1,6 @@
require 'date'
require 'action_view/helpers/tag_helper'
+require 'active_support/core_ext/array/extract_options'
require 'active_support/core_ext/date/conversions'
require 'active_support/core_ext/hash/slice'
require 'active_support/core_ext/object/with_options'
@@ -1040,14 +1041,38 @@ module ActionView
end
class FormBuilder
+ # Wraps ActionView::Helpers::DateHelper#date_select for form builders:
+ #
+ # <%= form_for @person do |f| %>
+ # <%= f.date_select :birth_date %>
+ # <%= f.submit %>
+ # <% end %>
+ #
+ # Please refer to the documentation of the base helper for details.
def date_select(method, options = {}, html_options = {})
@template.date_select(@object_name, method, objectify_options(options), html_options)
end
+ # Wraps ActionView::Helpers::DateHelper#time_select for form builders:
+ #
+ # <%= form_for @race do |f| %>
+ # <%= f.time_select :average_lap %>
+ # <%= f.submit %>
+ # <% end %>
+ #
+ # Please refer to the documentation of the base helper for details.
def time_select(method, options = {}, html_options = {})
@template.time_select(@object_name, method, objectify_options(options), html_options)
end
+ # Wraps ActionView::Helpers::DateHelper#datetime_select for form builders:
+ #
+ # <%= form_for @person do |f| %>
+ # <%= f.time_select :last_request_at %>
+ # <%= f.submit %>
+ # <% end %>
+ #
+ # Please refer to the documentation of the base helper for details.
def datetime_select(method, options = {}, html_options = {})
@template.datetime_select(@object_name, method, objectify_options(options), html_options)
end
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index 4a31de715d..3dae1fc87a 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -8,7 +8,6 @@ require 'action_view/model_naming'
require 'active_support/core_ext/class/attribute_accessors'
require 'active_support/core_ext/hash/slice'
require 'active_support/core_ext/string/output_safety'
-require 'active_support/core_ext/array/extract_options'
require 'active_support/core_ext/string/inflections'
module ActionView
@@ -771,8 +770,8 @@ module ActionView
# text_field(:post, :title, class: "create_input")
# # => <input type="text" id="post_title" name="post[title]" value="#{@post.title}" class="create_input" />
#
- # text_field(:session, :user, onchange: "if $('#session_user').value == 'admin' { alert('Your login can not be admin!'); }")
- # # => <input type="text" id="session_user" name="session[user]" value="#{@session.user}" onchange = "if $('#session_user').value == 'admin' { alert('Your login can not be admin!'); }"/>
+ # text_field(:session, :user, onchange: "if ($('#session_user').val() === 'admin') { alert('Your login can not be admin!'); }")
+ # # => <input type="text" id="session_user" name="session[user]" value="#{@session.user}" onchange="if ($('#session_user').val() === 'admin') { alert('Your login can not be admin!'); }"/>
#
# text_field(:snippet, :code, size: 20, class: 'code_input')
# # => <input type="text" id="snippet_code" name="snippet[code]" size="20" value="#{@snippet.code}" class="code_input" />
@@ -792,8 +791,8 @@ module ActionView
# password_field(:account, :secret, class: "form_input", value: @account.secret)
# # => <input type="password" id="account_secret" name="account[secret]" value="#{@account.secret}" class="form_input" />
#
- # password_field(:user, :password, onchange: "if $('user[password]').length > 30 { alert('Your password needs to be shorter!'); }")
- # # => <input type="password" id="user_password" name="user[password]" onchange = "if $('user[password]').length > 30 { alert('Your password needs to be shorter!'); }"/>
+ # password_field(:user, :password, onchange: "if ($('#user_password').val().length > 30) { alert('Your password needs to be shorter!'); }")
+ # # => <input type="password" id="user_password" name="user[password]" onchange="if ($('#user_password').val().length > 30) { alert('Your password needs to be shorter!'); }"/>
#
# password_field(:account, :pin, size: 20, class: 'form_input')
# # => <input type="password" id="account_pin" name="account[pin]" size="20" class="form_input" />
diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb
index ae7bfd1ec6..8b3a37a853 100644
--- a/actionpack/lib/action_view/helpers/form_options_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_options_helper.rb
@@ -2,6 +2,7 @@ require 'cgi'
require 'erb'
require 'action_view/helpers/form_helper'
require 'active_support/core_ext/string/output_safety'
+require 'active_support/core_ext/array/extract_options'
require 'active_support/core_ext/array/wrap'
module ActionView
@@ -756,26 +757,74 @@ module ActionView
end
class FormBuilder
+ # Wraps ActionView::Helpers::FormOptionsHelper#select for form builders:
+ #
+ # <%= form_for @post do |f| %>
+ # <%= f.select :person_id, Person.all.collect {|p| [ p.name, p.id ] }, { include_blank: true }) %>
+ # <%= f.submit %>
+ # <% end %>
+ #
+ # Please refer to the documentation of the base helper for details.
def select(method, choices, options = {}, html_options = {})
@template.select(@object_name, method, choices, objectify_options(options), @default_options.merge(html_options))
end
+ # Wraps ActionView::Helpers::FormOptionsHelper#collection_select for form builders:
+ #
+ # <%= form_for @post do |f| %>
+ # <%= f.collection_select :person_id, Author.all, :id, :name_with_initial, prompt: true %>
+ # <%= f.submit %>
+ # <% end %>
+ #
+ # Please refer to the documentation of the base helper for details.
def collection_select(method, collection, value_method, text_method, options = {}, html_options = {})
@template.collection_select(@object_name, method, collection, value_method, text_method, objectify_options(options), @default_options.merge(html_options))
end
+ # Wraps ActionView::Helpers::FormOptionsHelper#grouped_collection_select for form builders:
+ #
+ # <%= form_for @city do |f| %>
+ # <%= f.grouped_collection_select :country_id, :country_id, @continents, :countries, :name, :id, :name %>
+ # <%= f.submit %>
+ # <% end %>
+ #
+ # Please refer to the documentation of the base helper for details.
def grouped_collection_select(method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {})
@template.grouped_collection_select(@object_name, method, collection, group_method, group_label_method, option_key_method, option_value_method, objectify_options(options), @default_options.merge(html_options))
end
+ # Wraps ActionView::Helpers::FormOptionsHelper#time_zone_select for form builders:
+ #
+ # <%= form_for @user do |f| %>
+ # <%= f.time_zone_select :time_zone, nil, include_blank: true %>
+ # <%= f.submit %>
+ # <% end %>
+ #
+ # Please refer to the documentation of the base helper for details.
def time_zone_select(method, priority_zones = nil, options = {}, html_options = {})
@template.time_zone_select(@object_name, method, priority_zones, objectify_options(options), @default_options.merge(html_options))
end
+ # Wraps ActionView::Helpers::FormOptionsHelper#collection_check_boxes for form builders:
+ #
+ # <%= form_for @post do |f| %>
+ # <%= f.collection_check_boxes :author_ids, Author.all, :id, :name_with_initial %>
+ # <%= f.submit %>
+ # <% end %>
+ #
+ # Please refer to the documentation of the base helper for details.
def collection_check_boxes(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
@template.collection_check_boxes(@object_name, method, collection, value_method, text_method, objectify_options(options), @default_options.merge(html_options), &block)
end
+ # Wraps ActionView::Helpers::FormOptionsHelper#collection_radio_buttons for form builders:
+ #
+ # <%= form_for @post do |f| %>
+ # <%= f.collection_radio_buttons :author_id, Author.all, :id, :name_with_initial %>
+ # <%= f.submit %>
+ # <% end %>
+ #
+ # Please refer to the documentation of the base helper for details.
def collection_radio_buttons(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
@template.collection_radio_buttons(@object_name, method, collection, value_method, text_method, objectify_options(options), @default_options.merge(html_options), &block)
end
diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb
index cfdd7c77d8..878d3e0eda 100644
--- a/actionpack/lib/action_view/helpers/javascript_helper.rb
+++ b/actionpack/lib/action_view/helpers/javascript_helper.rb
@@ -13,8 +13,8 @@ module ActionView
"'" => "\\'"
}
- JS_ESCAPE_MAP["\342\200\250".force_encoding('UTF-8').encode!] = '&#x2028;'
- JS_ESCAPE_MAP["\342\200\251".force_encoding('UTF-8').encode!] = '&#x2029;'
+ JS_ESCAPE_MAP["\342\200\250".force_encoding(Encoding::UTF_8).encode!] = '&#x2028;'
+ JS_ESCAPE_MAP["\342\200\251".force_encoding(Encoding::UTF_8).encode!] = '&#x2029;'
# Escapes carriage returns and single and double quotes for JavaScript segments.
#
diff --git a/actionpack/lib/action_view/helpers/record_tag_helper.rb b/actionpack/lib/action_view/helpers/record_tag_helper.rb
index 271a194913..f767957fa9 100644
--- a/actionpack/lib/action_view/helpers/record_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/record_tag_helper.rb
@@ -92,7 +92,7 @@ module ActionView
# for each record.
def content_tag_for_single_record(tag_name, record, prefix, options, &block)
options = options ? options.dup : {}
- options[:class] = "#{dom_class(record, prefix)} #{options[:class]}".rstrip
+ options[:class] = [ dom_class(record, prefix), options[:class] ].compact
options[:id] = dom_id(record, prefix)
if block_given?
diff --git a/actionpack/lib/action_view/helpers/tags/collection_check_boxes.rb b/actionpack/lib/action_view/helpers/tags/collection_check_boxes.rb
index d27df45b5a..9655008fe2 100644
--- a/actionpack/lib/action_view/helpers/tags/collection_check_boxes.rb
+++ b/actionpack/lib/action_view/helpers/tags/collection_check_boxes.rb
@@ -13,13 +13,13 @@ module ActionView
end
end
- def render
+ def render(&block)
rendered_collection = render_collection do |item, value, text, default_html_options|
default_html_options[:multiple] = true
builder = instantiate_builder(CheckBoxBuilder, item, value, text, default_html_options)
if block_given?
- yield builder
+ @template_object.capture(builder, &block)
else
render_component(builder)
end
diff --git a/actionpack/lib/action_view/helpers/tags/collection_radio_buttons.rb b/actionpack/lib/action_view/helpers/tags/collection_radio_buttons.rb
index 81f2ecb2b3..893f4411e7 100644
--- a/actionpack/lib/action_view/helpers/tags/collection_radio_buttons.rb
+++ b/actionpack/lib/action_view/helpers/tags/collection_radio_buttons.rb
@@ -13,12 +13,12 @@ module ActionView
end
end
- def render
+ def render(&block)
render_collection do |item, value, text, default_html_options|
builder = instantiate_builder(RadioButtonBuilder, item, value, text, default_html_options)
if block_given?
- yield builder
+ @template_object.capture(builder, &block)
else
render_component(builder)
end
diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb
index bade121d44..5e20b557d8 100644
--- a/actionpack/lib/action_view/helpers/url_helper.rb
+++ b/actionpack/lib/action_view/helpers/url_helper.rb
@@ -514,7 +514,7 @@ module ActionView
"in a #request method"
end
- return false unless request.get?
+ return false unless request.get? || request.head?
url_string = url_for(options)
diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb
index b927c69260..f73d14c79b 100644
--- a/actionpack/lib/action_view/template.rb
+++ b/actionpack/lib/action_view/template.rb
@@ -80,8 +80,7 @@ module ActionView
# problems with converting the user's data to
# the <tt>default_internal</tt>.
#
- # To do so, simply raise the raise +WrongEncodingError+
- # as follows:
+ # To do so, simply raise +WrongEncodingError+ as follows:
#
# raise WrongEncodingError.new(
# problematic_string,
diff --git a/actionpack/lib/action_view/template/error.rb b/actionpack/lib/action_view/template/error.rb
index b479f991bc..a89d51221e 100644
--- a/actionpack/lib/action_view/template/error.rb
+++ b/actionpack/lib/action_view/template/error.rb
@@ -17,7 +17,7 @@ module ActionView
end
def message
- @string.force_encoding("BINARY")
+ @string.force_encoding(Encoding::ASCII_8BIT)
"Your template was not saved as valid #{@encoding}. Please " \
"either specify #{@encoding} as the encoding for your template " \
"in your text editor, or mark the template with its " \
diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb
index afbbece90f..5aaafc15c1 100644
--- a/actionpack/lib/action_view/template/handlers/erb.rb
+++ b/actionpack/lib/action_view/template/handlers/erb.rb
@@ -81,7 +81,7 @@ module ActionView
# wrong, we can still find an encoding tag
# (<%# encoding %>) inside the String using a regular
# expression
- template_source = template.source.dup.force_encoding("BINARY")
+ template_source = template.source.dup.force_encoding(Encoding::ASCII_8BIT)
erb = template_source.gsub(ENCODING_TAG, '')
encoding = $2
diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb
index 4479da5bc4..463f192d0c 100644
--- a/actionpack/lib/action_view/test_case.rb
+++ b/actionpack/lib/action_view/test_case.rb
@@ -122,7 +122,7 @@ module ActionView
class RenderedViewsCollection
def initialize
- @rendered_views ||= {}
+ @rendered_views ||= Hash.new { |hash, key| hash[key] = [] }
end
def add(view, locals)
@@ -134,6 +134,10 @@ module ActionView
@rendered_views[view]
end
+ def rendered_views
+ @rendered_views.keys
+ end
+
def view_rendered?(view, expected_locals)
locals_for(view).any? do |actual_locals|
expected_locals.all? {|key, value| value == actual_locals[key] }
diff --git a/actionpack/test/abstract/translation_test.rb b/actionpack/test/abstract/translation_test.rb
index 99064a8b87..4fdc480b43 100644
--- a/actionpack/test/abstract/translation_test.rb
+++ b/actionpack/test/abstract/translation_test.rb
@@ -1,39 +1,50 @@
require 'abstract_unit'
-# class TranslatingController < ActionController::Base
-# end
-
-class TranslationControllerTest < ActiveSupport::TestCase
- def setup
- @controller = ActionController::Base.new
- end
-
- def test_action_controller_base_responds_to_translate
- assert_respond_to @controller, :translate
- end
-
- def test_action_controller_base_responds_to_t
- assert_respond_to @controller, :t
- end
-
- def test_action_controller_base_responds_to_localize
- assert_respond_to @controller, :localize
- end
-
- def test_action_controller_base_responds_to_l
- assert_respond_to @controller, :l
- end
-
- def test_lazy_lookup
- expected = 'bar'
- @controller.stubs(:action_name => :index)
- I18n.stubs(:translate).with('action_controller.base.index.foo').returns(expected)
- assert_equal expected, @controller.t('.foo')
- end
-
- def test_default_translation
- key, expected = 'one.two' 'bar'
- I18n.stubs(:translate).with(key).returns(expected)
- assert_equal expected, @controller.t(key)
+module AbstractController
+ module Testing
+ class TranslationController < AbstractController::Base
+ include AbstractController::Translation
+ end
+
+ class TranslationControllerTest < ActiveSupport::TestCase
+ def setup
+ @controller = TranslationController.new
+ end
+
+ def test_action_controller_base_responds_to_translate
+ assert_respond_to @controller, :translate
+ end
+
+ def test_action_controller_base_responds_to_t
+ assert_respond_to @controller, :t
+ end
+
+ def test_action_controller_base_responds_to_localize
+ assert_respond_to @controller, :localize
+ end
+
+ def test_action_controller_base_responds_to_l
+ assert_respond_to @controller, :l
+ end
+
+ def test_lazy_lookup
+ expected = 'bar'
+ @controller.stubs(action_name: :index)
+ I18n.stubs(:translate).with('abstract_controller.testing.translation.index.foo').returns(expected)
+ assert_equal expected, @controller.t('.foo')
+ end
+
+ def test_default_translation
+ key, expected = 'one.two', 'bar'
+ I18n.stubs(:translate).with(key).returns(expected)
+ assert_equal expected, @controller.t(key)
+ end
+
+ def test_localize
+ time, expected = Time.gm(2000), 'Sat, 01 Jan 2000 00:00:00 +0000'
+ I18n.stubs(:localize).with(time).returns(expected)
+ assert_equal expected, @controller.l(time)
+ end
+ end
end
end
diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb
index bbcd289886..7157bccfb3 100644
--- a/actionpack/test/abstract_unit.rb
+++ b/actionpack/test/abstract_unit.rb
@@ -38,6 +38,8 @@ end
ActiveSupport::Dependencies.hook!
+Thread.abort_on_exception = true
+
# Show backtraces for deprecated behavior for quicker cleanup.
ActiveSupport::Deprecation.debug = true
diff --git a/actionpack/test/activerecord/form_helper_activerecord_test.rb b/actionpack/test/activerecord/form_helper_activerecord_test.rb
new file mode 100644
index 0000000000..2e302c65a7
--- /dev/null
+++ b/actionpack/test/activerecord/form_helper_activerecord_test.rb
@@ -0,0 +1,91 @@
+require 'active_record_unit'
+require 'fixtures/project'
+require 'fixtures/developer'
+
+class FormHelperActiveRecordTest < ActionView::TestCase
+ tests ActionView::Helpers::FormHelper
+
+ def form_for(*)
+ @output_buffer = super
+ end
+
+ def setup
+ @developer = Developer.new
+ @developer.id = 123
+ @developer.name = "developer #123"
+
+ @project = Project.new
+ @project.id = 321
+ @project.name = "project #321"
+ @project.save
+
+ @developer.projects << @project
+ @developer.save
+ end
+
+ def teardown
+ Project.delete(321)
+ Developer.delete(123)
+ end
+
+ Routes = ActionDispatch::Routing::RouteSet.new
+ Routes.draw do
+ resources :developers do
+ resources :projects
+ end
+ end
+
+ def _routes
+ Routes
+ end
+
+ include Routes.url_helpers
+
+ def test_nested_fields_for_with_child_index_option_override_on_a_nested_attributes_collection_association
+ form_for(@developer) do |f|
+ concat f.fields_for(:projects, @developer.projects.first, :child_index => 'abc') { |cf|
+ concat cf.text_field(:name)
+ }
+ end
+
+ expected = whole_form('/developers/123', 'edit_developer_123', 'edit_developer', :method => 'patch') do
+ '<input id="developer_projects_attributes_abc_name" name="developer[projects_attributes][abc][name]" type="text" value="project #321" />' +
+ '<input id="developer_projects_attributes_abc_id" name="developer[projects_attributes][abc][id]" type="hidden" value="321" />'
+ end
+
+ assert_dom_equal expected, output_buffer
+ end
+
+ protected
+
+ def hidden_fields(method = nil)
+ txt = %{<div style="margin:0;padding:0;display:inline">}
+ txt << %{<input name="utf8" type="hidden" value="&#x2713;" />}
+ if method && !%w(get post).include?(method.to_s)
+ txt << %{<input name="_method" type="hidden" value="#{method}" />}
+ end
+ txt << %{</div>}
+ end
+
+ def form_text(action = "/", id = nil, html_class = nil, remote = nil, multipart = nil, method = nil)
+ txt = %{<form accept-charset="UTF-8" action="#{action}"}
+ txt << %{ enctype="multipart/form-data"} if multipart
+ txt << %{ data-remote="true"} if remote
+ txt << %{ class="#{html_class}"} if html_class
+ txt << %{ id="#{id}"} if id
+ method = method.to_s == "get" ? "get" : "post"
+ txt << %{ method="#{method}">}
+ end
+
+ def whole_form(action = "/", id = nil, html_class = nil, options = nil)
+ contents = block_given? ? yield : ""
+
+ if options.is_a?(Hash)
+ method, remote, multipart = options.values_at(:method, :remote, :multipart)
+ else
+ method = options
+ end
+
+ form_text(action, id, html_class, remote, multipart, method) + hidden_fields(method) + contents + "</form>"
+ end
+end \ No newline at end of file
diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb
index e2239c05c7..72b882539c 100644
--- a/actionpack/test/controller/integration_test.rb
+++ b/actionpack/test/controller/integration_test.rb
@@ -751,13 +751,17 @@ class UrlOptionsIntegrationTest < ActionDispatch::IntegrationTest
assert_equal "http://bar.com/foo", foos_url
end
- test "test can override default url options" do
+ def test_can_override_default_url_options
+ original_host = default_url_options.dup
+
default_url_options[:host] = "foobar.com"
assert_equal "http://foobar.com/foo", foos_url
get "/bar"
assert_response :success
assert_equal "http://foobar.com/foo", foos_url
+ ensure
+ ActionDispatch::Integration::Session.default_url_options = self.default_url_options = original_host
end
test "current request path parameters are recalled" do
diff --git a/actionpack/test/controller/layout_test.rb b/actionpack/test/controller/layout_test.rb
index 365fa04570..71bcfd664e 100644
--- a/actionpack/test/controller/layout_test.rb
+++ b/actionpack/test/controller/layout_test.rb
@@ -1,5 +1,6 @@
require 'abstract_unit'
require 'rbconfig'
+require 'active_support/core_ext/array/extract_options'
# The view_paths array must be set on Base and not LayoutTest so that LayoutTest's inherited
# method has access to the view_paths array when looking for a layout to automatically assign.
diff --git a/actionpack/test/controller/localized_templates_test.rb b/actionpack/test/controller/localized_templates_test.rb
index 41ff2f3809..bac1d02977 100644
--- a/actionpack/test/controller/localized_templates_test.rb
+++ b/actionpack/test/controller/localized_templates_test.rb
@@ -9,14 +9,20 @@ class LocalizedTemplatesTest < ActionController::TestCase
tests LocalizedController
def test_localized_template_is_used
+ old_locale = I18n.locale
I18n.locale = :de
get :hello_world
assert_equal "Gutten Tag", @response.body
+ ensure
+ I18n.locale = old_locale
end
def test_default_locale_template_is_used_when_locale_is_missing
+ old_locale = I18n.locale
I18n.locale = :dk
get :hello_world
assert_equal "Hello World", @response.body
+ ensure
+ I18n.locale = old_locale
end
-end \ No newline at end of file
+end
diff --git a/actionpack/test/controller/parameters/nested_parameters_test.rb b/actionpack/test/controller/parameters/nested_parameters_test.rb
index 6df849c4e2..91df527dec 100644
--- a/actionpack/test/controller/parameters/nested_parameters_test.rb
+++ b/actionpack/test/controller/parameters/nested_parameters_test.rb
@@ -2,6 +2,10 @@ require 'abstract_unit'
require 'action_controller/metal/strong_parameters'
class NestedParametersTest < ActiveSupport::TestCase
+ def assert_filtered_out(params, key)
+ assert !params.has_key?(key), "key #{key.inspect} has not been filtered out"
+ end
+
test "permitted nested parameters" do
params = ActionController::Parameters.new({
book: {
@@ -11,6 +15,8 @@ class NestedParametersTest < ActiveSupport::TestCase
born: "1564-04-26"
}, {
name: "Christopher Marlowe"
+ }, {
+ name: %w(malicious injected names)
}],
details: {
pages: 200,
@@ -30,10 +36,12 @@ class NestedParametersTest < ActiveSupport::TestCase
assert_equal "William Shakespeare", permitted[:book][:authors][0][:name]
assert_equal "Christopher Marlowe", permitted[:book][:authors][1][:name]
assert_equal 200, permitted[:book][:details][:pages]
- assert_nil permitted[:book][:id]
- assert_nil permitted[:book][:details][:genre]
- assert_nil permitted[:book][:authors][0][:born]
- assert_nil permitted[:magazine]
+
+ assert_filtered_out permitted, :magazine
+ assert_filtered_out permitted[:book], :id
+ assert_filtered_out permitted[:book][:details], :genre
+ assert_filtered_out permitted[:book][:authors][0], :born
+ assert_filtered_out permitted[:book][:authors][2], :name
end
test "permitted nested parameters with a string or a symbol as a key" do
@@ -63,25 +71,25 @@ class NestedParametersTest < ActiveSupport::TestCase
test "nested arrays with strings" do
params = ActionController::Parameters.new({
- :book => {
- :genres => ["Tragedy"]
+ book: {
+ genres: ["Tragedy"]
}
})
- permitted = params.permit :book => :genres
+ permitted = params.permit book: {genres: []}
assert_equal ["Tragedy"], permitted[:book][:genres]
end
test "permit may specify symbols or strings" do
params = ActionController::Parameters.new({
- :book => {
- :title => "Romeo and Juliet",
- :author => "William Shakespeare"
+ book: {
+ title: "Romeo and Juliet",
+ author: "William Shakespeare"
},
- :magazine => "Shakespeare Today"
+ magazine: "Shakespeare Today"
})
- permitted = params.permit({:book => ["title", :author]}, "magazine")
+ permitted = params.permit({book: ["title", :author]}, "magazine")
assert_equal "Romeo and Juliet", permitted[:book][:title]
assert_equal "William Shakespeare", permitted[:book][:author]
assert_equal "Shakespeare Today", permitted[:magazine]
@@ -127,16 +135,38 @@ class NestedParametersTest < ActiveSupport::TestCase
book: {
authors_attributes: {
:'0' => { name: 'William Shakespeare', age_of_death: '52' },
- :'-1' => { name: 'Unattributed Assistant' }
+ :'1' => { name: 'Unattributed Assistant' },
+ :'2' => { name: %w(injected names)}
}
}
})
permitted = params.permit book: { authors_attributes: [ :name ] }
assert_not_nil permitted[:book][:authors_attributes]['0']
- assert_not_nil permitted[:book][:authors_attributes]['-1']
- assert_nil permitted[:book][:authors_attributes]['0'][:age_of_death]
+ assert_not_nil permitted[:book][:authors_attributes]['1']
+ assert_empty permitted[:book][:authors_attributes]['2']
assert_equal 'William Shakespeare', permitted[:book][:authors_attributes]['0'][:name]
- assert_equal 'Unattributed Assistant', permitted[:book][:authors_attributes]['-1'][:name]
+ assert_equal 'Unattributed Assistant', permitted[:book][:authors_attributes]['1'][:name]
+
+ assert_filtered_out permitted[:book][:authors_attributes]['0'], :age_of_death
+ end
+
+ test "fields_for-style nested params with negative numbers" do
+ params = ActionController::Parameters.new({
+ book: {
+ authors_attributes: {
+ :'-1' => { name: 'William Shakespeare', age_of_death: '52' },
+ :'-2' => { name: 'Unattributed Assistant' }
+ }
+ }
+ })
+ permitted = params.permit book: { authors_attributes: [:name] }
+
+ assert_not_nil permitted[:book][:authors_attributes]['-1']
+ assert_not_nil permitted[:book][:authors_attributes]['-2']
+ assert_equal 'William Shakespeare', permitted[:book][:authors_attributes]['-1'][:name]
+ assert_equal 'Unattributed Assistant', permitted[:book][:authors_attributes]['-2'][:name]
+
+ assert_filtered_out permitted[:book][:authors_attributes]['-1'], :age_of_death
end
end
diff --git a/actionpack/test/controller/parameters/parameters_permit_test.rb b/actionpack/test/controller/parameters/parameters_permit_test.rb
index 7cc71fe6dc..aadb142660 100644
--- a/actionpack/test/controller/parameters/parameters_permit_test.rb
+++ b/actionpack/test/controller/parameters/parameters_permit_test.rb
@@ -1,11 +1,133 @@
require 'abstract_unit'
+require 'action_dispatch/http/upload'
require 'action_controller/metal/strong_parameters'
class ParametersPermitTest < ActiveSupport::TestCase
+ def assert_filtered_out(params, key)
+ assert !params.has_key?(key), "key #{key.inspect} has not been filtered out"
+ end
+
setup do
@params = ActionController::Parameters.new({ person: {
age: "32", name: { first: "David", last: "Heinemeier Hansson" }
}})
+
+ @struct_fields = []
+ %w(0 1 12).each do |number|
+ ['', 'i', 'f'].each do |suffix|
+ @struct_fields << "sf(#{number}#{suffix})"
+ end
+ end
+ end
+
+ test 'if nothing is permitted, the hash becomes empty' do
+ params = ActionController::Parameters.new(id: '1234')
+ permitted = params.permit
+ assert permitted.permitted?
+ assert permitted.empty?
+ end
+
+ test 'key: permitted scalar values' do
+ values = ['a', :a, nil]
+ values += [0, 1.0, 2**128, BigDecimal.new(1)]
+ values += [true, false]
+ values += [Date.today, Time.now, DateTime.now]
+ values += [STDOUT, StringIO.new, ActionDispatch::Http::UploadedFile.new(tempfile: __FILE__)]
+
+ values.each do |value|
+ params = ActionController::Parameters.new(id: value)
+ permitted = params.permit(:id)
+ assert_equal value, permitted[:id]
+
+ @struct_fields.each do |sf|
+ params = ActionController::Parameters.new(sf => value)
+ permitted = params.permit(:sf)
+ assert_equal value, permitted[sf]
+ end
+ end
+ end
+
+ test 'key: unknown keys are filtered out' do
+ params = ActionController::Parameters.new(id: '1234', injected: 'injected')
+ permitted = params.permit(:id)
+ assert_equal '1234', permitted[:id]
+ assert_filtered_out permitted, :injected
+ end
+
+ test 'key: arrays are filtered out' do
+ [[], [1], ['1']].each do |array|
+ params = ActionController::Parameters.new(id: array)
+ permitted = params.permit(:id)
+ assert_filtered_out permitted, :id
+
+ @struct_fields.each do |sf|
+ params = ActionController::Parameters.new(sf => array)
+ permitted = params.permit(:sf)
+ assert_filtered_out permitted, sf
+ end
+ end
+ end
+
+ test 'key: hashes are filtered out' do
+ [{}, {foo: 1}, {foo: 'bar'}].each do |hash|
+ params = ActionController::Parameters.new(id: hash)
+ permitted = params.permit(:id)
+ assert_filtered_out permitted, :id
+
+ @struct_fields.each do |sf|
+ params = ActionController::Parameters.new(sf => hash)
+ permitted = params.permit(:sf)
+ assert_filtered_out permitted, sf
+ end
+ end
+ end
+
+ test 'key: non-permitted scalar values are filtered out' do
+ params = ActionController::Parameters.new(id: Object.new)
+ permitted = params.permit(:id)
+ assert_filtered_out permitted, :id
+
+ @struct_fields.each do |sf|
+ params = ActionController::Parameters.new(sf => Object.new)
+ permitted = params.permit(:sf)
+ assert_filtered_out permitted, sf
+ end
+ end
+
+ test 'key: it is not assigned if not present in params' do
+ params = ActionController::Parameters.new(name: 'Joe')
+ permitted = params.permit(:id)
+ assert !permitted.has_key?(:id)
+ end
+
+ test 'key to empty array: empty arrays pass' do
+ params = ActionController::Parameters.new(id: [])
+ permitted = params.permit(id: [])
+ assert_equal [], permitted[:id]
+ end
+
+ test 'key to empty array: arrays of permitted scalars pass' do
+ [['foo'], [1], ['foo', 'bar'], [1, 2, 3]].each do |array|
+ params = ActionController::Parameters.new(id: array)
+ permitted = params.permit(id: [])
+ assert_equal array, permitted[:id]
+ end
+ end
+
+ test 'key to empty array: permitted scalar values do not pass' do
+ ['foo', 1].each do |permitted_scalar|
+ params = ActionController::Parameters.new(id: permitted_scalar)
+ permitted = params.permit(id: [])
+ assert_filtered_out permitted, :id
+ end
+ end
+
+ test 'key to empty array: arrays of non-permitted scalar do not pass' do
+ [[Object.new], [[]], [[1]], [{}], [{id: '1'}]].each do |non_permitted_scalar|
+ params = ActionController::Parameters.new(id: non_permitted_scalar)
+ permitted = params.permit(id: [])
+ assert_filtered_out permitted, :id
+ end
end
test "fetch raises ParameterMissing exception" do
@@ -73,10 +195,6 @@ class ParametersPermitTest < ActiveSupport::TestCase
assert_equal "Jonas", @params[:person][:family][:brother]
end
- test "permitting parameters that are not there should not include the keys" do
- assert !@params.permit(:person, :funky).has_key?(:funky)
- end
-
test "permit state is kept on a dup" do
@params.permit!
assert_equal @params.permitted?, @params.dup.permitted?
diff --git a/actionpack/test/controller/request_forgery_protection_test.rb b/actionpack/test/controller/request_forgery_protection_test.rb
index 523a8d0572..c272e785c2 100644
--- a/actionpack/test/controller/request_forgery_protection_test.rb
+++ b/actionpack/test/controller/request_forgery_protection_test.rb
@@ -66,6 +66,19 @@ class RequestForgeryProtectionControllerUsingException < ActionController::Base
protect_from_forgery :only => %w(index meta), :with => :exception
end
+class RequestForgeryProtectionControllerUsingNullSession < ActionController::Base
+ protect_from_forgery :with => :null_session
+
+ def signed
+ cookies.signed[:foo] = 'bar'
+ render :nothing => true
+ end
+
+ def encrypted
+ cookies.encrypted[:foo] = 'bar'
+ render :nothing => true
+ end
+end
class FreeCookieController < RequestForgeryProtectionControllerUsingResetSession
self.allow_forgery_protection = false
@@ -170,6 +183,10 @@ module RequestForgeryProtectionTests
assert_not_blocked { get :index }
end
+ def test_should_allow_head
+ assert_not_blocked { head :index }
+ end
+
def test_should_allow_post_without_token_on_unsafe_action
assert_not_blocked { post :unsafe }
end
@@ -283,6 +300,28 @@ class RequestForgeryProtectionControllerUsingResetSessionTest < ActionController
end
end
+class NullSessionDummyKeyGenerator
+ def generate_key(secret)
+ '03312270731a2ed0d11ed091c2338a06'
+ end
+end
+
+class RequestForgeryProtectionControllerUsingNullSessionTest < ActionController::TestCase
+ def setup
+ @request.env[ActionDispatch::Cookies::GENERATOR_KEY] = NullSessionDummyKeyGenerator.new
+ end
+
+ test 'should allow to set signed cookies' do
+ post :signed
+ assert_response :ok
+ end
+
+ test 'should allow to set encrypted cookies' do
+ post :encrypted
+ assert_response :ok
+ end
+end
+
class RequestForgeryProtectionControllerUsingExceptionTest < ActionController::TestCase
include RequestForgeryProtectionTests
def assert_blocked
diff --git a/actionpack/test/controller/resources_test.rb b/actionpack/test/controller/resources_test.rb
index 305659b219..9aea7e860a 100644
--- a/actionpack/test/controller/resources_test.rb
+++ b/actionpack/test/controller/resources_test.rb
@@ -1,6 +1,7 @@
require 'abstract_unit'
require 'active_support/core_ext/object/try'
require 'active_support/core_ext/object/with_options'
+require 'active_support/core_ext/array/extract_options'
class ResourcesTest < ActionController::TestCase
def test_default_restful_routes
diff --git a/actionpack/test/controller/webservice_test.rb b/actionpack/test/controller/webservice_test.rb
index 0480295056..19d5652d81 100644
--- a/actionpack/test/controller/webservice_test.rb
+++ b/actionpack/test/controller/webservice_test.rb
@@ -129,19 +129,6 @@ class WebServiceTest < ActionDispatch::IntegrationTest
$stderr = STDERR
end
- def test_register_and_use_yaml
- with_test_route_set do
- with_params_parsers Mime::YAML => Proc.new { |d| YAML.load(d) } do
- post "/", {"entry" => "loaded from yaml"}.to_yaml,
- {'CONTENT_TYPE' => 'application/x-yaml'}
-
- assert_equal 'entry', @controller.response.body
- assert @controller.params.has_key?(:entry)
- assert_equal 'loaded from yaml', @controller.params["entry"]
- end
- end
- end
-
def test_register_and_use_xml_simple
with_test_route_set do
with_params_parsers Mime::XML => Proc.new { |data| Hash.from_xml(data)['request'].with_indifferent_access } do
diff --git a/actionpack/test/dispatch/best_standards_support_test.rb b/actionpack/test/dispatch/best_standards_support_test.rb
deleted file mode 100644
index 551bb9621a..0000000000
--- a/actionpack/test/dispatch/best_standards_support_test.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-require 'abstract_unit'
-
-class BestStandardsSupportTest < ActiveSupport::TestCase
- def test_with_best_standards_support
- _, headers, _ = app(true, {}).call({})
- assert_equal "IE=Edge,chrome=1", headers["X-UA-Compatible"]
- end
-
- def test_with_builtin_best_standards_support
- _, headers, _ = app(:builtin, {}).call({})
- assert_equal "IE=Edge", headers["X-UA-Compatible"]
- end
-
- def test_without_best_standards_support
- _, headers, _ = app(false, {}).call({})
- assert_equal nil, headers["X-UA-Compatible"]
- end
-
- def test_appends_to_app_headers_without_duplication_after_multiple_requests
- app_headers = { "X-UA-Compatible" => "requiresActiveX=true" }
- _, headers, _ = app(true, app_headers).call({})
- _, headers, _ = app(true, app_headers).call({})
-
- expects = "requiresActiveX=true,IE=Edge,chrome=1"
- assert_equal expects, headers["X-UA-Compatible"]
- end
-
- private
-
- def app(type, headers)
- app = proc { [200, headers, "response"] }
- ActionDispatch::BestStandardsSupport.new(app, type)
- end
-
-end
diff --git a/actionpack/test/dispatch/cookies_test.rb b/actionpack/test/dispatch/cookies_test.rb
index ffa91d63c4..66d2cade22 100644
--- a/actionpack/test/dispatch/cookies_test.rb
+++ b/actionpack/test/dispatch/cookies_test.rb
@@ -160,6 +160,36 @@ class CookiesTest < ActionController::TestCase
@request.host = "www.nextangle.com"
end
+ def test_fetch
+ x = Object.new
+ assert_not request.cookie_jar.key?('zzzzzz')
+ assert_equal x, request.cookie_jar.fetch('zzzzzz', x)
+ assert_not request.cookie_jar.key?('zzzzzz')
+ end
+
+ def test_fetch_exists
+ x = Object.new
+ request.cookie_jar['foo'] = 'bar'
+ assert_equal 'bar', request.cookie_jar.fetch('foo', x)
+ end
+
+ def test_fetch_block
+ x = Object.new
+ assert_not request.cookie_jar.key?('zzzzzz')
+ assert_equal x, request.cookie_jar.fetch('zzzzzz') { x }
+ end
+
+ def test_key_is_to_s
+ request.cookie_jar['foo'] = 'bar'
+ assert_equal 'bar', request.cookie_jar.fetch(:foo)
+ end
+
+ def test_fetch_type_error
+ assert_raises(KeyError) do
+ request.cookie_jar.fetch(:omglolwut)
+ end
+ end
+
def test_each
request.cookie_jar['foo'] = :bar
list = []
@@ -211,13 +241,13 @@ class CookiesTest < ActionController::TestCase
def test_setting_cookie_for_fourteen_days
get :authenticate_for_fourteen_days
- assert_cookie_header "user_name=david; path=/; expires=Mon, 10-Oct-2005 05:00:00 GMT"
+ assert_cookie_header "user_name=david; path=/; expires=Mon, 10 Oct 2005 05:00:00 -0000"
assert_equal({"user_name" => "david"}, @response.cookies)
end
def test_setting_cookie_for_fourteen_days_with_symbols
get :authenticate_for_fourteen_days_with_symbols
- assert_cookie_header "user_name=david; path=/; expires=Mon, 10-Oct-2005 05:00:00 GMT"
+ assert_cookie_header "user_name=david; path=/; expires=Mon, 10 Oct 2005 05:00:00 -0000"
assert_equal({"user_name" => "david"}, @response.cookies)
end
@@ -250,7 +280,7 @@ class CookiesTest < ActionController::TestCase
def test_multiple_cookies
get :set_multiple_cookies
assert_equal 2, @response.cookies.size
- assert_cookie_header "user_name=david; path=/; expires=Mon, 10-Oct-2005 05:00:00 GMT\nlogin=XJ-122; path=/"
+ assert_cookie_header "user_name=david; path=/; expires=Mon, 10 Oct 2005 05:00:00 -0000\nlogin=XJ-122; path=/"
assert_equal({"login" => "XJ-122", "user_name" => "david"}, @response.cookies)
end
@@ -261,14 +291,14 @@ class CookiesTest < ActionController::TestCase
def test_expiring_cookie
request.cookies[:user_name] = 'Joe'
get :logout
- assert_cookie_header "user_name=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT"
+ assert_cookie_header "user_name=; path=/; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
assert_equal({"user_name" => nil}, @response.cookies)
end
def test_delete_cookie_with_path
request.cookies[:user_name] = 'Joe'
get :delete_cookie_with_path
- assert_cookie_header "user_name=; path=/beaten; expires=Thu, 01-Jan-1970 00:00:00 GMT"
+ assert_cookie_header "user_name=; path=/beaten; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
end
def test_delete_unexisting_cookie
@@ -330,7 +360,7 @@ class CookiesTest < ActionController::TestCase
def test_delete_and_set_cookie
request.cookies[:user_name] = 'Joe'
get :delete_and_set_cookie
- assert_cookie_header "user_name=david; path=/; expires=Mon, 10-Oct-2005 05:00:00 GMT"
+ assert_cookie_header "user_name=david; path=/; expires=Mon, 10 Oct 2005 05:00:00 -0000"
assert_equal({"user_name" => "david"}, @response.cookies)
end
@@ -435,7 +465,7 @@ class CookiesTest < ActionController::TestCase
request.cookies[:user_name] = 'Joe'
get :delete_cookie_with_domain
assert_response :success
- assert_cookie_header "user_name=; domain=.nextangle.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT"
+ assert_cookie_header "user_name=; domain=.nextangle.com; path=/; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
end
def test_cookie_with_all_domain_option_and_tld_length
@@ -462,7 +492,7 @@ class CookiesTest < ActionController::TestCase
request.cookies[:user_name] = 'Joe'
get :delete_cookie_with_domain_and_tld
assert_response :success
- assert_cookie_header "user_name=; domain=.nextangle.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT"
+ assert_cookie_header "user_name=; domain=.nextangle.com; path=/; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
end
def test_cookie_with_several_preset_domains_using_one_of_these_domains
@@ -491,7 +521,7 @@ class CookiesTest < ActionController::TestCase
request.cookies[:user_name] = 'Joe'
get :delete_cookie_with_domains
assert_response :success
- assert_cookie_header "user_name=; domain=example2.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT"
+ assert_cookie_header "user_name=; domain=example2.com; path=/; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
end
def test_deletings_cookie_with_several_preset_domains_using_other_domain
@@ -499,7 +529,7 @@ class CookiesTest < ActionController::TestCase
request.cookies[:user_name] = 'Joe'
get :delete_cookie_with_domains
assert_response :success
- assert_cookie_header "user_name=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT"
+ assert_cookie_header "user_name=; path=/; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
end
def test_cookies_hash_is_indifferent_access
diff --git a/actionpack/test/dispatch/response_test.rb b/actionpack/test/dispatch/response_test.rb
index 185a9e9b18..74f5253c11 100644
--- a/actionpack/test/dispatch/response_test.rb
+++ b/actionpack/test/dispatch/response_test.rb
@@ -35,7 +35,7 @@ class ResponseTest < ActiveSupport::TestCase
end
def test_response_body_encoding
- body = ["hello".encode('utf-8')]
+ body = ["hello".encode(Encoding::UTF_8)]
response = ActionDispatch::Response.new 200, {}, body
assert_equal Encoding::UTF_8, response.body.encoding
end
@@ -129,7 +129,7 @@ class ResponseTest < ActiveSupport::TestCase
@response.set_cookie("login", :value => "foo&bar", :path => "/", :expires => Time.utc(2005, 10, 10,5))
status, headers, body = @response.to_a
- assert_equal "user_name=david; path=/\nlogin=foo%26bar; path=/; expires=Mon, 10-Oct-2005 05:00:00 GMT", headers["Set-Cookie"]
+ assert_equal "user_name=david; path=/\nlogin=foo%26bar; path=/; expires=Mon, 10 Oct 2005 05:00:00 -0000", headers["Set-Cookie"]
assert_equal({"login" => "foo&bar", "user_name" => "david"}, @response.cookies)
@response.delete_cookie("login")
@@ -182,7 +182,8 @@ class ResponseTest < ActiveSupport::TestCase
ActionDispatch::Response.default_headers = {
'X-Frame-Options' => 'DENY',
'X-Content-Type-Options' => 'nosniff',
- 'X-XSS-Protection' => '1;'
+ 'X-XSS-Protection' => '1;',
+ 'X-UA-Compatible' => 'chrome=1'
}
resp = ActionDispatch::Response.new.tap { |response|
response.body = 'Hello'
@@ -192,6 +193,7 @@ class ResponseTest < ActiveSupport::TestCase
assert_equal('DENY', resp.headers['X-Frame-Options'])
assert_equal('nosniff', resp.headers['X-Content-Type-Options'])
assert_equal('1;', resp.headers['X-XSS-Protection'])
+ assert_equal('chrome=1', resp.headers['X-UA-Compatible'])
ensure
ActionDispatch::Response.default_headers = nil
end
diff --git a/actionpack/test/dispatch/routing/inspector_test.rb b/actionpack/test/dispatch/routing/inspector_test.rb
index c7dcb5a683..55221f87c4 100644
--- a/actionpack/test/dispatch/routing/inspector_test.rb
+++ b/actionpack/test/dispatch/routing/inspector_test.rb
@@ -21,6 +21,14 @@ module ActionDispatch
inspector.format(ActionDispatch::Routing::ConsoleFormatter.new, options[:filter]).split("\n")
end
+ def test_json_regexp_converter
+ @set.draw do
+ get '/cart', :to => 'cart#show'
+ end
+ route = ActionDispatch::Routing::RouteWrapper.new(@set.routes.first)
+ assert_equal "^\\/cart(?:\\.([^\\/.?]+))?$", route.json_regexp
+ end
+
def test_displaying_routes_for_engines
engine = Class.new(Rails::Engine) do
def self.inspect
diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb
index da7474e73c..143733254b 100644
--- a/actionpack/test/dispatch/routing_test.rb
+++ b/actionpack/test/dispatch/routing_test.rb
@@ -1031,6 +1031,18 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
assert_equal 'users/home#index', @response.body
end
+ def test_namespace_containing_numbers
+ draw do
+ namespace :v2 do
+ resources :subscriptions
+ end
+ end
+
+ get '/v2/subscriptions'
+ assert_equal 'v2/subscriptions#index', @response.body
+ assert_equal '/v2/subscriptions', v2_subscriptions_path
+ end
+
def test_articles_with_id
draw do
controller :articles do
@@ -2678,6 +2690,15 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
assert_equal '0c0c0b68-d24b-11e1-a861-001ff3fffe6f', @request.params[:download]
end
+ def test_action_from_path_is_not_frozen
+ draw do
+ get 'search' => 'search'
+ end
+
+ get '/search'
+ assert !@request.params[:action].frozen?
+ end
+
private
def draw(&block)
@@ -2824,21 +2845,52 @@ class TestNamespaceWithControllerOption < ActionDispatch::IntegrationTest
end
end
- DefaultScopeRoutes = ActionDispatch::Routing::RouteSet.new
- DefaultScopeRoutes.draw do
- namespace :admin do
- resources :storage_files, :controller => "StorageFiles"
- end
+ def draw(&block)
+ @app = ActionDispatch::Routing::RouteSet.new
+ @app.draw(&block)
end
- def app
- DefaultScopeRoutes
- end
+ def test_valid_controller_options_inside_namespace
+ draw do
+ namespace :admin do
+ resources :storage_files, :controller => "storage_files"
+ end
+ end
- def test_controller_options
get '/admin/storage_files'
assert_equal "admin/storage_files#index", @response.body
end
+
+ def test_resources_with_valid_namespaced_controller_option
+ draw do
+ resources :storage_files, :controller => 'admin/storage_files'
+ end
+
+ get 'storage_files'
+ assert_equal "admin/storage_files#index", @response.body
+ end
+
+ def test_warn_with_ruby_constant_syntax_controller_option
+ e = assert_raise(ArgumentError) do
+ draw do
+ namespace :admin do
+ resources :storage_files, :controller => "StorageFiles"
+ end
+ end
+ end
+
+ assert_match "'admin/StorageFiles' is not a supported controller name", e.message
+ end
+
+ def test_warn_with_ruby_constant_syntax_namespaced_controller_option
+ e = assert_raise(ArgumentError) do
+ draw do
+ resources :storage_files, :controller => 'Admin::StorageFiles'
+ end
+ end
+
+ assert_match "'Admin::StorageFiles' is not a supported controller name", e.message
+ end
end
class TestDefaultScope < ActionDispatch::IntegrationTest
diff --git a/actionpack/test/dispatch/session/cookie_store_test.rb b/actionpack/test/dispatch/session/cookie_store_test.rb
index 1677dee524..d8bf22dec8 100644
--- a/actionpack/test/dispatch/session/cookie_store_test.rb
+++ b/actionpack/test/dispatch/session/cookie_store_test.rb
@@ -276,7 +276,7 @@ class CookieStoreTest < ActionDispatch::IntegrationTest
# First request accesses the session
time = Time.local(2008, 4, 24)
Time.stubs(:now).returns(time)
- expected_expiry = (time + 5.hours).gmtime.strftime("%a, %d-%b-%Y %H:%M:%S GMT")
+ expected_expiry = (time + 5.hours).gmtime.strftime("%a, %d %b %Y %H:%M:%S -0000")
cookies[SessionKey] = SignedBar
@@ -290,7 +290,7 @@ class CookieStoreTest < ActionDispatch::IntegrationTest
# Second request does not access the session
time = Time.local(2008, 4, 25)
Time.stubs(:now).returns(time)
- expected_expiry = (time + 5.hours).gmtime.strftime("%a, %d-%b-%Y %H:%M:%S GMT")
+ expected_expiry = (time + 5.hours).gmtime.strftime("%a, %d %b %Y %H:%M:%S -0000")
get '/no_session_access'
assert_response :success
diff --git a/actionpack/test/dispatch/session/test_session_test.rb b/actionpack/test/dispatch/session/test_session_test.rb
index 904398f563..d30461a623 100644
--- a/actionpack/test/dispatch/session/test_session_test.rb
+++ b/actionpack/test/dispatch/session/test_session_test.rb
@@ -2,8 +2,8 @@ require 'abstract_unit'
require 'stringio'
class ActionController::TestSessionTest < ActiveSupport::TestCase
- def test_ctor_allows_setting
- session = ActionController::TestSession.new({:one => 'one', :two => 'two'})
+ def test_initialize_with_values
+ session = ActionController::TestSession.new(one: 'one', two: 'two')
assert_equal('one', session[:one])
assert_equal('two', session[:two])
end
@@ -23,15 +23,21 @@ class ActionController::TestSessionTest < ActiveSupport::TestCase
end
def test_calling_update_with_params_passes_to_attributes
- session = ActionController::TestSession.new()
+ session = ActionController::TestSession.new
session.update('key' => 'value')
assert_equal('value', session[:key])
end
- def test_clear_emptys_session
- session = ActionController::TestSession.new({:one => 'one', :two => 'two'})
+ def test_clear_empties_session
+ session = ActionController::TestSession.new(one: 'one', two: 'two')
session.clear
assert_nil(session[:one])
assert_nil(session[:two])
end
+
+ def test_keys_and_values
+ session = ActionController::TestSession.new(one: '1', two: '2')
+ assert_equal %w(one two), session.keys
+ assert_equal %w(1 2), session.values
+ end
end
diff --git a/actionpack/test/dispatch/test_request_test.rb b/actionpack/test/dispatch/test_request_test.rb
index 6047631ba3..3db862c810 100644
--- a/actionpack/test/dispatch/test_request_test.rb
+++ b/actionpack/test/dispatch/test_request_test.rb
@@ -18,7 +18,7 @@ class TestRequestTest < ActiveSupport::TestCase
assert_equal "0.0.0.0", env.delete("REMOTE_ADDR")
assert_equal "Rails Testing", env.delete("HTTP_USER_AGENT")
- assert_equal [1, 1], env.delete("rack.version")
+ assert_equal [1, 2], env.delete("rack.version")
assert_equal "", env.delete("rack.input").string
assert_kind_of StringIO, env.delete("rack.errors")
assert_equal true, env.delete("rack.multithread")
@@ -40,10 +40,10 @@ class TestRequestTest < ActiveSupport::TestCase
req.cookie_jar["login"] = "XJ-122"
assert_cookies({"user_name" => "david", "login" => "XJ-122"}, req.cookie_jar)
- assert_nothing_raised do
+ assert_nothing_raised do
req.cookie_jar["login"] = nil
assert_cookies({"user_name" => "david", "login" => nil}, req.cookie_jar)
- end
+ end
req.cookie_jar.delete(:login)
assert_cookies({"user_name" => "david"}, req.cookie_jar)
diff --git a/actionpack/test/fixtures/developer.rb b/actionpack/test/fixtures/developer.rb
index dd14548fac..4941463015 100644
--- a/actionpack/test/fixtures/developer.rb
+++ b/actionpack/test/fixtures/developer.rb
@@ -2,6 +2,7 @@ class Developer < ActiveRecord::Base
has_and_belongs_to_many :projects
has_many :replies
has_many :topics, :through => :replies
+ accepts_nested_attributes_for :projects
end
class DeVeLoPeR < ActiveRecord::Base
diff --git a/actionpack/test/fixtures/test/_directory/_partial_with_locales.html.erb b/actionpack/test/fixtures/test/_directory/_partial_with_locales.html.erb
new file mode 100644
index 0000000000..1cc8d41475
--- /dev/null
+++ b/actionpack/test/fixtures/test/_directory/_partial_with_locales.html.erb
@@ -0,0 +1 @@
+Hello <%= name %>
diff --git a/actionpack/test/fixtures/test/render_partial_inside_directory.html.erb b/actionpack/test/fixtures/test/render_partial_inside_directory.html.erb
new file mode 100644
index 0000000000..1461b95186
--- /dev/null
+++ b/actionpack/test/fixtures/test/render_partial_inside_directory.html.erb
@@ -0,0 +1 @@
+<%= render partial: 'test/_directory/partial_with_locales', locals: {'name' => 'Jane'} %>
diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb
index 82c9d383ac..11614a45dc 100644
--- a/actionpack/test/template/asset_tag_helper_test.rb
+++ b/actionpack/test/template/asset_tag_helper_test.rb
@@ -443,7 +443,8 @@ class AssetTagHelperTest < ActionView::TestCase
[nil, '/', '/foo/bar/', 'foo/bar/'].each do |prefix|
assert_equal 'Rails', image_alt("#{prefix}rails.png")
assert_equal 'Rails', image_alt("#{prefix}rails-9c0a079bdd7701d7e729bd956823d153.png")
- assert_equal 'Avatar-0000', image_alt("#{prefix}avatar-0000.png")
+ assert_equal 'Long file name with hyphens', image_alt("#{prefix}long-file-name-with-hyphens.png")
+ assert_equal 'Long file name with underscores', image_alt("#{prefix}long_file_name_with_underscores.png")
end
end
diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb
index f9890a2eef..268bab6ad2 100644
--- a/actionpack/test/template/form_helper_test.rb
+++ b/actionpack/test/template/form_helper_test.rb
@@ -15,26 +15,26 @@ class FormHelperTest < ActionView::TestCase
# Create "label" locale for testing I18n label helpers
I18n.backend.store_translations 'label', {
- :activemodel => {
- :attributes => {
- :post => {
- :cost => "Total cost"
+ activemodel: {
+ attributes: {
+ post: {
+ cost: "Total cost"
}
}
},
- :helpers => {
- :label => {
- :post => {
- :body => "Write entire text here",
- :color => {
- :red => "Rojo"
+ helpers: {
+ label: {
+ post: {
+ body: "Write entire text here",
+ color: {
+ red: "Rojo"
},
- :comments => {
- :body => "Write body here"
+ comments: {
+ body: "Write body here"
}
},
- :tag => {
- :value => "Tag"
+ tag: {
+ value: "Tag"
}
}
}
@@ -42,13 +42,13 @@ class FormHelperTest < ActionView::TestCase
# Create "submit" locale for testing I18n submit helpers
I18n.backend.store_translations 'submit', {
- :helpers => {
- :submit => {
- :create => 'Create %{model}',
- :update => 'Confirm %{model} changes',
- :submit => 'Save changes',
- :another_post => {
- :update => 'Update your %{model}'
+ helpers: {
+ submit: {
+ create: 'Create %{model}',
+ update: 'Confirm %{model} changes',
+ submit: 'Save changes',
+ another_post: {
+ update: 'Update your %{model}'
}
}
}
@@ -57,11 +57,11 @@ class FormHelperTest < ActionView::TestCase
@post = Post.new
@comment = Comment.new
def @post.errors()
- Class.new{
+ Class.new {
def [](field); field == "author_name" ? ["can't be empty"] : [] end
def empty?() false end
def count() 1 end
- def full_messages() [ "Author name can't be empty" ] end
+ def full_messages() ["Author name can't be empty"] end
}.new
end
def @post.to_key; [123]; end
@@ -96,8 +96,8 @@ class FormHelperTest < ActionView::TestCase
end
end
- get "/foo", :to => "controller#action"
- root :to => "main#index"
+ get "/foo", to: "controller#action"
+ root to: "main#index"
end
def _routes
@@ -108,9 +108,11 @@ class FormHelperTest < ActionView::TestCase
def url_for(object)
@url_for_options = object
+
if object.is_a?(Hash) && object[:use_route].blank? && object[:controller].blank?
- object.merge!(:controller => "main", :action => "index")
+ object.merge!(controller: "main", action: "index")
end
+
super
end
@@ -124,10 +126,13 @@ class FormHelperTest < ActionView::TestCase
def test_label
assert_dom_equal('<label for="post_title">Title</label>', label("post", "title"))
- assert_dom_equal('<label for="post_title">The title goes here</label>', label("post", "title", "The title goes here"))
+ assert_dom_equal(
+ '<label for="post_title">The title goes here</label>',
+ label("post", "title", "The title goes here")
+ )
assert_dom_equal(
'<label class="title_label" for="post_title">Title</label>',
- label("post", "title", nil, :class => 'title_label')
+ label("post", "title", nil, class: 'title_label')
)
assert_dom_equal('<label for="post_secret">Secret?</label>', label("post", "secret?"))
end
@@ -160,28 +165,31 @@ class FormHelperTest < ActionView::TestCase
def test_label_with_locales_and_options
old_locale, I18n.locale = I18n.locale, :label
- assert_dom_equal('<label for="post_body" class="post_body">Write entire text here</label>', label(:post, :body, :class => 'post_body'))
+ assert_dom_equal(
+ '<label for="post_body" class="post_body">Write entire text here</label>',
+ label(:post, :body, class: "post_body")
+ )
ensure
I18n.locale = old_locale
end
def test_label_with_locales_and_value
old_locale, I18n.locale = I18n.locale, :label
- assert_dom_equal('<label for="post_color_red">Rojo</label>', label(:post, :color, :value => "red"))
+ assert_dom_equal('<label for="post_color_red">Rojo</label>', label(:post, :color, value: "red"))
ensure
I18n.locale = old_locale
end
def test_label_with_locales_and_nested_attributes
old_locale, I18n.locale = I18n.locale, :label
- form_for(@post, :html => { :id => 'create-post' }) do |f|
+ form_for(@post, html: { id: 'create-post' }) do |f|
f.fields_for(:comments) do |cf|
concat cf.label(:body)
end
end
- expected = whole_form("/posts/123", "create-post" , "edit_post", :method => 'patch') do
- "<label for=\"post_comments_attributes_0_body\">Write body here</label>"
+ expected = whole_form("/posts/123", "create-post", "edit_post", method: "patch") do
+ '<label for="post_comments_attributes_0_body">Write body here</label>'
end
assert_dom_equal expected, output_buffer
@@ -191,14 +199,14 @@ class FormHelperTest < ActionView::TestCase
def test_label_with_locales_fallback_and_nested_attributes
old_locale, I18n.locale = I18n.locale, :label
- form_for(@post, :html => { :id => 'create-post' }) do |f|
+ form_for(@post, html: { id: 'create-post' }) do |f|
f.fields_for(:tags) do |cf|
concat cf.label(:value)
end
end
- expected = whole_form("/posts/123", "create-post" , "edit_post", :method => 'patch') do
- "<label for=\"post_tags_attributes_0_value\">Tag</label>"
+ expected = whole_form("/posts/123", "create-post", "edit_post", method: "patch") do
+ '<label for="post_tags_attributes_0_value">Tag</label>'
end
assert_dom_equal expected, output_buffer
@@ -207,7 +215,7 @@ class FormHelperTest < ActionView::TestCase
end
def test_label_with_for_attribute_as_symbol
- assert_dom_equal('<label for="my_for">Title</label>', label(:post, :title, nil, :for => "my_for"))
+ assert_dom_equal('<label for="my_for">Title</label>', label(:post, :title, nil, for: "my_for"))
end
def test_label_with_for_attribute_as_string
@@ -215,61 +223,93 @@ class FormHelperTest < ActionView::TestCase
end
def test_label_does_not_generate_for_attribute_when_given_nil
- assert_dom_equal('<label>Title</label>', label(:post, :title, :for => nil))
+ assert_dom_equal('<label>Title</label>', label(:post, :title, for: nil))
end
def test_label_with_id_attribute_as_symbol
- assert_dom_equal('<label for="post_title" id="my_id">Title</label>', label(:post, :title, nil, :id => "my_id"))
+ assert_dom_equal(
+ '<label for="post_title" id="my_id">Title</label>',
+ label(:post, :title, nil, id: "my_id")
+ )
end
def test_label_with_id_attribute_as_string
- assert_dom_equal('<label for="post_title" id="my_id">Title</label>', label(:post, :title, nil, "id" => "my_id"))
+ assert_dom_equal(
+ '<label for="post_title" id="my_id">Title</label>',
+ label(:post, :title, nil, "id" => "my_id")
+ )
end
def test_label_with_for_and_id_attributes_as_symbol
- assert_dom_equal('<label for="my_for" id="my_id">Title</label>', label(:post, :title, nil, :for => "my_for", :id => "my_id"))
+ assert_dom_equal(
+ '<label for="my_for" id="my_id">Title</label>',
+ label(:post, :title, nil, for: "my_for", id: "my_id")
+ )
end
def test_label_with_for_and_id_attributes_as_string
- assert_dom_equal('<label for="my_for" id="my_id">Title</label>', label(:post, :title, nil, "for" => "my_for", "id" => "my_id"))
+ assert_dom_equal(
+ '<label for="my_for" id="my_id">Title</label>',
+ label(:post, :title, nil, "for" => "my_for", "id" => "my_id")
+ )
end
def test_label_for_radio_buttons_with_value
- assert_dom_equal('<label for="post_title_great_title">The title goes here</label>', label("post", "title", "The title goes here", :value => "great_title"))
- assert_dom_equal('<label for="post_title_great_title">The title goes here</label>', label("post", "title", "The title goes here", :value => "great title"))
+ assert_dom_equal(
+ '<label for="post_title_great_title">The title goes here</label>',
+ label("post", "title", "The title goes here", value: "great_title")
+ )
+ assert_dom_equal(
+ '<label for="post_title_great_title">The title goes here</label>',
+ label("post", "title", "The title goes here", value: "great title")
+ )
end
def test_label_with_block
- assert_dom_equal('<label for="post_title">The title, please:</label>', label(:post, :title) { "The title, please:" })
+ assert_dom_equal(
+ '<label for="post_title">The title, please:</label>',
+ label(:post, :title) { "The title, please:" }
+ )
end
def test_label_with_block_and_options
- assert_dom_equal('<label for="my_for">The title, please:</label>', label(:post, :title, "for" => "my_for") { "The title, please:" })
+ assert_dom_equal(
+ '<label for="my_for">The title, please:</label>',
+ label(:post, :title, "for" => "my_for") { "The title, please:" }
+ )
end
def test_label_with_block_in_erb
- assert_equal "<label for=\"post_message\">\n Message\n <input id=\"post_message\" name=\"post[message]\" type=\"text\" />\n</label>", view.render("test/label_with_block")
+ assert_equal(
+ %{<label for="post_message">\n Message\n <input id="post_message" name="post[message]" type="text" />\n</label>},
+ view.render("test/label_with_block")
+ )
end
def test_text_field
assert_dom_equal(
- '<input id="post_title" name="post[title]" type="text" value="Hello World" />', text_field("post", "title")
+ '<input id="post_title" name="post[title]" type="text" value="Hello World" />',
+ text_field("post", "title")
)
assert_dom_equal(
- '<input id="post_title" name="post[title]" type="password" />', password_field("post", "title")
+ '<input id="post_title" name="post[title]" type="password" />',
+ password_field("post", "title")
)
assert_dom_equal(
- '<input id="post_title" name="post[title]" type="password" value="Hello World" />', password_field("post", "title", :value => @post.title)
+ '<input id="post_title" name="post[title]" type="password" value="Hello World" />',
+ password_field("post", "title", value: @post.title)
)
assert_dom_equal(
- '<input id="person_name" name="person[name]" type="password" />', password_field("person", "name")
+ '<input id="person_name" name="person[name]" type="password" />',
+ password_field("person", "name")
)
end
def test_text_field_with_escapes
@post.title = "<b>Hello World</b>"
assert_dom_equal(
- '<input id="post_title" name="post[title]" type="text" value="&lt;b&gt;Hello World&lt;/b&gt;" />', text_field("post", "title")
+ '<input id="post_title" name="post[title]" type="text" value="&lt;b&gt;Hello World&lt;/b&gt;" />',
+ text_field("post", "title")
)
end
@@ -284,29 +324,29 @@ class FormHelperTest < ActionView::TestCase
def test_text_field_with_options
expected = '<input id="post_title" name="post[title]" size="35" type="text" value="Hello World" />'
assert_dom_equal expected, text_field("post", "title", "size" => 35)
- assert_dom_equal expected, text_field("post", "title", :size => 35)
+ assert_dom_equal expected, text_field("post", "title", size: 35)
end
def test_text_field_assuming_size
expected = '<input id="post_title" maxlength="35" name="post[title]" size="35" type="text" value="Hello World" />'
assert_dom_equal expected, text_field("post", "title", "maxlength" => 35)
- assert_dom_equal expected, text_field("post", "title", :maxlength => 35)
+ assert_dom_equal expected, text_field("post", "title", maxlength: 35)
end
def test_text_field_removing_size
expected = '<input id="post_title" maxlength="35" name="post[title]" type="text" value="Hello World" />'
assert_dom_equal expected, text_field("post", "title", "maxlength" => 35, "size" => nil)
- assert_dom_equal expected, text_field("post", "title", :maxlength => 35, :size => nil)
+ assert_dom_equal expected, text_field("post", "title", maxlength: 35, size: nil)
end
def test_text_field_with_nil_value
expected = '<input id="post_title" name="post[title]" type="text" />'
- assert_dom_equal expected, text_field("post", "title", :value => nil)
+ assert_dom_equal expected, text_field("post", "title", value: nil)
end
def test_text_field_with_nil_name
expected = '<input id="post_title" type="text" value="Hello World" />'
- assert_dom_equal expected, text_field("post", "title", :name => nil)
+ assert_dom_equal expected, text_field("post", "title", name: nil)
end
def test_text_field_doesnt_change_param_values
@@ -322,31 +362,41 @@ class FormHelperTest < ActionView::TestCase
end
def test_hidden_field
- assert_dom_equal '<input id="post_title" name="post[title]" type="hidden" value="Hello World" />',
+ assert_dom_equal(
+ '<input id="post_title" name="post[title]" type="hidden" value="Hello World" />',
hidden_field("post", "title")
- assert_dom_equal '<input id="post_secret" name="post[secret]" type="hidden" value="1" />',
- hidden_field("post", "secret?")
+ )
+ assert_dom_equal(
+ '<input id="post_secret" name="post[secret]" type="hidden" value="1" />',
+ hidden_field("post", "secret?")
+ )
end
def test_hidden_field_with_escapes
@post.title = "<b>Hello World</b>"
- assert_dom_equal '<input id="post_title" name="post[title]" type="hidden" value="&lt;b&gt;Hello World&lt;/b&gt;" />',
+ assert_dom_equal(
+ '<input id="post_title" name="post[title]" type="hidden" value="&lt;b&gt;Hello World&lt;/b&gt;" />',
hidden_field("post", "title")
+ )
end
def test_hidden_field_with_nil_value
expected = '<input id="post_title" name="post[title]" type="hidden" />'
- assert_dom_equal expected, hidden_field("post", "title", :value => nil)
+ assert_dom_equal expected, hidden_field("post", "title", value: nil)
end
def test_hidden_field_with_options
- assert_dom_equal '<input id="post_title" name="post[title]" type="hidden" value="Something Else" />',
- hidden_field("post", "title", :value => "Something Else")
+ assert_dom_equal(
+ '<input id="post_title" name="post[title]" type="hidden" value="Something Else" />',
+ hidden_field("post", "title", value: "Something Else")
+ )
end
def test_text_field_with_custom_type
- assert_dom_equal '<input id="user_email" name="user[email]" type="email" />',
- text_field("user", "email", :type => "email")
+ assert_dom_equal(
+ '<input id="user_email" name="user[email]" type="email" />',
+ text_field("user", "email", type: "email")
+ )
end
def test_check_box_is_html_safe
@@ -371,7 +421,7 @@ class FormHelperTest < ActionView::TestCase
def test_check_box_checked_if_option_checked_is_present
assert_dom_equal(
'<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
- check_box("post", "secret" ,{"checked"=>"checked"})
+ check_box("post", "secret", "checked"=>"checked")
)
end
@@ -410,7 +460,10 @@ class FormHelperTest < ActionView::TestCase
def test_check_box_with_include_hidden_false
@post.secret = false
- assert_dom_equal('<input id="post_secret" name="post[secret]" type="checkbox" value="1" />', check_box("post", "secret", :include_hidden => false))
+ assert_dom_equal(
+ '<input id="post_secret" name="post[secret]" type="checkbox" value="1" />',
+ check_box("post", "secret", include_hidden: false)
+ )
end
def test_check_box_with_explicit_checked_and_unchecked_values_when_object_value_is_string
@@ -517,11 +570,11 @@ class FormHelperTest < ActionView::TestCase
@post.comment_ids = [2,3]
assert_dom_equal(
'<input name="post[comment_ids][]" type="hidden" value="0" /><input id="post_comment_ids_1" name="post[comment_ids][]" type="checkbox" value="1" />',
- check_box("post", "comment_ids", { :multiple => true }, 1)
+ check_box("post", "comment_ids", { multiple: true }, 1)
)
assert_dom_equal(
'<input name="post[comment_ids][]" type="hidden" value="0" /><input checked="checked" id="post_comment_ids_3" name="post[comment_ids][]" type="checkbox" value="3" />',
- check_box("post", "comment_ids", { :multiple => true }, 3)
+ check_box("post", "comment_ids", { multiple: true }, 3)
)
end
@@ -529,11 +582,11 @@ class FormHelperTest < ActionView::TestCase
@post.comment_ids = [2,3]
assert_dom_equal(
'<input name="post[foo][comment_ids][]" type="hidden" value="0" /><input id="post_foo_comment_ids_1" name="post[foo][comment_ids][]" type="checkbox" value="1" />',
- check_box("post", "comment_ids", { :multiple => true, :index => "foo" }, 1)
+ check_box("post", "comment_ids", { multiple: true, index: "foo" }, 1)
)
assert_dom_equal(
'<input name="post[bar][comment_ids][]" type="hidden" value="0" /><input checked="checked" id="post_bar_comment_ids_3" name="post[bar][comment_ids][]" type="checkbox" value="3" />',
- check_box("post", "comment_ids", { :multiple => true, :index => "bar" }, 3)
+ check_box("post", "comment_ids", { multiple: true, index: "bar" }, 3)
)
end
@@ -541,14 +594,14 @@ class FormHelperTest < ActionView::TestCase
def test_checkbox_disabled_disables_hidden_field
assert_dom_equal(
'<input name="post[secret]" type="hidden" value="0" disabled="disabled"/><input checked="checked" disabled="disabled" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
- check_box("post", "secret", { :disabled => true })
+ check_box("post", "secret", { disabled: true })
)
end
def test_checkbox_form_html5_attribute
assert_dom_equal(
'<input form="new_form" name="post[secret]" type="hidden" value="0" /><input checked="checked" form="new_form" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
- check_box("post", "secret", :form => "new_form")
+ check_box("post", "secret", form: "new_form")
)
end
@@ -577,7 +630,7 @@ class FormHelperTest < ActionView::TestCase
def test_radio_button_respects_passed_in_id
assert_dom_equal('<input checked="checked" id="foo" name="post[secret]" type="radio" value="1" />',
- radio_button("post", "secret", "1", :id=>"foo")
+ radio_button("post", "secret", "1", id: "foo")
)
end
@@ -599,7 +652,7 @@ class FormHelperTest < ActionView::TestCase
end
def test_text_area_with_escapes
- @post.body = "Back to <i>the</i> hill and over it again!"
+ @post.body = "Back to <i>the</i> hill and over it again!"
assert_dom_equal(
%{<textarea id="post_body" name="post[body]">\nBack to &lt;i&gt;the&lt;/i&gt; hill and over it again!</textarea>},
text_area("post", "body")
@@ -609,12 +662,12 @@ class FormHelperTest < ActionView::TestCase
def test_text_area_with_alternate_value
assert_dom_equal(
%{<textarea id="post_body" name="post[body]">\nTesting alternate values.</textarea>},
- text_area("post", "body", :value => 'Testing alternate values.')
+ text_area("post", "body", value: "Testing alternate values.")
)
end
def test_text_area_with_html_entities
- @post.body = "The HTML Entity for & is &amp;"
+ @post.body = "The HTML Entity for & is &amp;"
assert_dom_equal(
%{<textarea id="post_body" name="post[body]">\nThe HTML Entity for &amp; is &amp;amp;</textarea>},
text_area("post", "body")
@@ -624,7 +677,7 @@ class FormHelperTest < ActionView::TestCase
def test_text_area_with_size_option
assert_dom_equal(
%{<textarea cols="183" id="post_body" name="post[body]" rows="820">\nBack to the hill and over it again!</textarea>},
- text_area("post", "body", :size => "183x820")
+ text_area("post", "body", size: "183x820")
)
end
@@ -666,7 +719,7 @@ class FormHelperTest < ActionView::TestCase
min_value = DateTime.new(2000, 6, 15)
max_value = DateTime.new(2010, 8, 15)
step = 2
- assert_dom_equal(expected, date_field("post", "written_on", :min => min_value, :max => max_value, :step => step))
+ assert_dom_equal(expected, date_field("post", "written_on", min: min_value, max: max_value, step: step))
end
def test_date_field_with_timewithzone_value
@@ -701,7 +754,7 @@ class FormHelperTest < ActionView::TestCase
min_value = DateTime.new(2000, 6, 15, 20, 45, 30)
max_value = DateTime.new(2010, 8, 15, 10, 25, 00)
step = 60
- assert_dom_equal(expected, time_field("post", "written_on", :min => min_value, :max => max_value, :step => step))
+ assert_dom_equal(expected, time_field("post", "written_on", min: min_value, max: max_value, step: step))
end
def test_time_field_with_timewithzone_value
@@ -736,7 +789,7 @@ class FormHelperTest < ActionView::TestCase
min_value = DateTime.new(2000, 6, 15, 20, 45, 30)
max_value = DateTime.new(2010, 8, 15, 10, 25, 00)
step = 60
- assert_dom_equal(expected, datetime_field("post", "written_on", :min => min_value, :max => max_value, :step => step))
+ assert_dom_equal(expected, datetime_field("post", "written_on", min: min_value, max: max_value, step: step))
end
def test_datetime_field_with_timewithzone_value
@@ -771,7 +824,7 @@ class FormHelperTest < ActionView::TestCase
min_value = DateTime.new(2000, 6, 15, 20, 45, 30)
max_value = DateTime.new(2010, 8, 15, 10, 25, 00)
step = 60
- assert_dom_equal(expected, datetime_local_field("post", "written_on", :min => min_value, :max => max_value, :step => step))
+ assert_dom_equal(expected, datetime_local_field("post", "written_on", min: min_value, max: max_value, step: step))
end
def test_datetime_local_field_with_timewithzone_value
@@ -812,7 +865,7 @@ class FormHelperTest < ActionView::TestCase
min_value = DateTime.new(2000, 2, 13)
max_value = DateTime.new(2010, 12, 23)
step = 2
- assert_dom_equal(expected, month_field("post", "written_on", :min => min_value, :max => max_value, :step => step))
+ assert_dom_equal(expected, month_field("post", "written_on", min: min_value, max: max_value, step: step))
end
def test_month_field_with_timewithzone_value
@@ -847,7 +900,7 @@ class FormHelperTest < ActionView::TestCase
min_value = DateTime.new(2000, 2, 13)
max_value = DateTime.new(2010, 12, 23)
step = 2
- assert_dom_equal(expected, week_field("post", "written_on", :min => min_value, :max => max_value, :step => step))
+ assert_dom_equal(expected, week_field("post", "written_on", min: min_value, max: max_value, step: step))
end
def test_week_field_with_timewithzone_value
@@ -871,21 +924,22 @@ class FormHelperTest < ActionView::TestCase
def test_number_field
expected = %{<input name="order[quantity]" max="9" id="order_quantity" type="number" min="1" />}
- assert_dom_equal(expected, number_field("order", "quantity", :in => 1...10))
+ assert_dom_equal(expected, number_field("order", "quantity", in: 1...10))
expected = %{<input name="order[quantity]" size="30" max="9" id="order_quantity" type="number" min="1" />}
- assert_dom_equal(expected, number_field("order", "quantity", :size => 30, :in => 1...10))
+ assert_dom_equal(expected, number_field("order", "quantity", size: 30, in: 1...10))
end
def test_range_input
expected = %{<input name="hifi[volume]" step="0.1" max="11" id="hifi_volume" type="range" min="0" />}
- assert_dom_equal(expected, range_field("hifi", "volume", :in => 0..11, :step => 0.1))
+ assert_dom_equal(expected, range_field("hifi", "volume", in: 0..11, step: 0.1))
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", :size => 30, :in => 0..11, :step => 0.1))
+ assert_dom_equal(expected, range_field("hifi", "volume", size: 30, in: 0..11, step: 0.1))
end
def test_explicit_name
assert_dom_equal(
- '<input id="post_title" name="dont guess" type="text" value="Hello World" />', text_field("post", "title", "name" => "dont guess")
+ '<input id="post_title" name="dont guess" type="text" value="Hello World" />',
+ text_field("post", "title", "name" => "dont guess")
)
assert_dom_equal(
%{<textarea id="post_body" name="really!">\nBack to the hill and over it again!</textarea>},
@@ -895,17 +949,24 @@ class FormHelperTest < ActionView::TestCase
'<input name="i mean it" type="hidden" value="0" /><input checked="checked" id="post_secret" name="i mean it" type="checkbox" value="1" />',
check_box("post", "secret", "name" => "i mean it")
)
- assert_dom_equal text_field("post", "title", "name" => "dont guess"),
- text_field("post", "title", :name => "dont guess")
- assert_dom_equal text_area("post", "body", "name" => "really!"),
- text_area("post", "body", :name => "really!")
- assert_dom_equal check_box("post", "secret", "name" => "i mean it"),
- check_box("post", "secret", :name => "i mean it")
+ assert_dom_equal(
+ text_field("post", "title", "name" => "dont guess"),
+ text_field("post", "title", name: "dont guess")
+ )
+ assert_dom_equal(
+ text_area("post", "body", "name" => "really!"),
+ text_area("post", "body", name: "really!")
+ )
+ assert_dom_equal(
+ check_box("post", "secret", "name" => "i mean it"),
+ check_box("post", "secret", name: "i mean it")
+ )
end
def test_explicit_id
assert_dom_equal(
- '<input id="dont guess" name="post[title]" type="text" value="Hello World" />', text_field("post", "title", "id" => "dont guess")
+ '<input id="dont guess" name="post[title]" type="text" value="Hello World" />',
+ text_field("post", "title", "id" => "dont guess")
)
assert_dom_equal(
%{<textarea id="really!" name="post[body]">\nBack to the hill and over it again!</textarea>},
@@ -915,17 +976,24 @@ class FormHelperTest < ActionView::TestCase
'<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="i mean it" name="post[secret]" type="checkbox" value="1" />',
check_box("post", "secret", "id" => "i mean it")
)
- assert_dom_equal text_field("post", "title", "id" => "dont guess"),
- text_field("post", "title", :id => "dont guess")
- assert_dom_equal text_area("post", "body", "id" => "really!"),
- text_area("post", "body", :id => "really!")
- assert_dom_equal check_box("post", "secret", "id" => "i mean it"),
- check_box("post", "secret", :id => "i mean it")
+ assert_dom_equal(
+ text_field("post", "title", "id" => "dont guess"),
+ text_field("post", "title", id: "dont guess")
+ )
+ assert_dom_equal(
+ text_area("post", "body", "id" => "really!"),
+ text_area("post", "body", id: "really!")
+ )
+ assert_dom_equal(
+ check_box("post", "secret", "id" => "i mean it"),
+ check_box("post", "secret", id: "i mean it")
+ )
end
def test_nil_id
assert_dom_equal(
- '<input name="post[title]" type="text" value="Hello World" />', text_field("post", "title", "id" => nil)
+ '<input name="post[title]" type="text" value="Hello World" />',
+ text_field("post", "title", "id" => nil)
)
assert_dom_equal(
%{<textarea name="post[body]">\nBack to the hill and over it again!</textarea>},
@@ -943,14 +1011,22 @@ class FormHelperTest < ActionView::TestCase
'<select name="post[secret]"></select>',
select("post", "secret", [], {}, "id" => nil)
)
- assert_dom_equal text_field("post", "title", "id" => nil),
- text_field("post", "title", :id => nil)
- assert_dom_equal text_area("post", "body", "id" => nil),
- text_area("post", "body", :id => nil)
- assert_dom_equal check_box("post", "secret", "id" => nil),
- check_box("post", "secret", :id => nil)
- assert_dom_equal radio_button("post", "secret", "0", "id" => nil),
- radio_button("post", "secret", "0", :id => nil)
+ assert_dom_equal(
+ text_field("post", "title", "id" => nil),
+ text_field("post", "title", id: nil)
+ )
+ assert_dom_equal(
+ text_area("post", "body", "id" => nil),
+ text_area("post", "body", id: nil)
+ )
+ assert_dom_equal(
+ check_box("post", "secret", "id" => nil),
+ check_box("post", "secret", id: nil)
+ )
+ assert_dom_equal(
+ radio_button("post", "secret", "0", "id" => nil),
+ radio_button("post", "secret", "0", id: nil)
+ )
end
def test_index
@@ -995,40 +1071,42 @@ class FormHelperTest < ActionView::TestCase
)
assert_dom_equal(
text_field("post", "title", "index" => 5, 'id' => nil),
- text_field("post", "title", :index => 5, :id => nil)
+ text_field("post", "title", index: 5, id: nil)
)
assert_dom_equal(
text_area("post", "body", "index" => 5, 'id' => nil),
- text_area("post", "body", :index => 5, :id => nil)
+ text_area("post", "body", index: 5, id: nil)
)
assert_dom_equal(
check_box("post", "secret", "index" => 5, 'id' => nil),
- check_box("post", "secret", :index => 5, :id => nil)
+ check_box("post", "secret", index: 5, id: nil)
)
end
def test_auto_index
pid = 123
assert_dom_equal(
- "<label for=\"post_#{pid}_title\">Title</label>",
+ %{<label for="post_#{pid}_title">Title</label>},
label("post[]", "title")
)
assert_dom_equal(
- "<input id=\"post_#{pid}_title\" name=\"post[#{pid}][title]\" type=\"text\" value=\"Hello World\" />", text_field("post[]","title")
+ %{<input id="post_#{pid}_title" name="post[#{pid}][title]" type="text" value="Hello World" />},
+ text_field("post[]","title")
)
assert_dom_equal(
- "<textarea id=\"post_#{pid}_body\" name=\"post[#{pid}][body]\">\nBack to the hill and over it again!</textarea>",
+ %{<textarea id="post_#{pid}_body" name="post[#{pid}][body]">\nBack to the hill and over it again!</textarea>},
text_area("post[]", "body")
)
assert_dom_equal(
- "<input name=\"post[#{pid}][secret]\" type=\"hidden\" value=\"0\" /><input checked=\"checked\" id=\"post_#{pid}_secret\" name=\"post[#{pid}][secret]\" type=\"checkbox\" value=\"1\" />",
+ %{<input name="post[#{pid}][secret]" type="hidden" value="0" /><input checked="checked" id="post_#{pid}_secret" name="post[#{pid}][secret]" type="checkbox" value="1" />},
check_box("post[]", "secret")
)
assert_dom_equal(
- "<input checked=\"checked\" id=\"post_#{pid}_title_hello_world\" name=\"post[#{pid}][title]\" type=\"radio\" value=\"Hello World\" />",
+ %{<input checked="checked" id="post_#{pid}_title_hello_world" name="post[#{pid}][title]" type="radio" value="Hello World" />},
radio_button("post[]", "title", "Hello World")
)
- assert_dom_equal("<input id=\"post_#{pid}_title_goodbye_world\" name=\"post[#{pid}][title]\" type=\"radio\" value=\"Goodbye World\" />",
+ assert_dom_equal(
+ %{<input id="post_#{pid}_title_goodbye_world" name="post[#{pid}][title]" type="radio" value="Goodbye World" />},
radio_button("post[]", "title", "Goodbye World")
)
end
@@ -1036,48 +1114,49 @@ class FormHelperTest < ActionView::TestCase
def test_auto_index_with_nil_id
pid = 123
assert_dom_equal(
- "<input name=\"post[#{pid}][title]\" type=\"text\" value=\"Hello World\" />",
- text_field("post[]","title", :id => nil)
+ %{<input name="post[#{pid}][title]" type="text" value="Hello World" />},
+ text_field("post[]", "title", id: nil)
)
assert_dom_equal(
- "<textarea name=\"post[#{pid}][body]\">\nBack to the hill and over it again!</textarea>",
- text_area("post[]", "body", :id => nil)
+ %{<textarea name="post[#{pid}][body]">\nBack to the hill and over it again!</textarea>},
+ text_area("post[]", "body", id: nil)
)
assert_dom_equal(
- "<input name=\"post[#{pid}][secret]\" type=\"hidden\" value=\"0\" /><input checked=\"checked\" name=\"post[#{pid}][secret]\" type=\"checkbox\" value=\"1\" />",
- check_box("post[]", "secret", :id => nil)
+ %{<input name="post[#{pid}][secret]" type="hidden" value="0" /><input checked="checked" name="post[#{pid}][secret]" type="checkbox" value="1" />},
+ check_box("post[]", "secret", id: nil)
)
assert_dom_equal(
-"<input checked=\"checked\" name=\"post[#{pid}][title]\" type=\"radio\" value=\"Hello World\" />",
- radio_button("post[]", "title", "Hello World", :id => nil)
+ %{<input checked="checked" name="post[#{pid}][title]" type="radio" value="Hello World" />},
+ radio_button("post[]", "title", "Hello World", id: nil)
)
- assert_dom_equal("<input name=\"post[#{pid}][title]\" type=\"radio\" value=\"Goodbye World\" />",
- radio_button("post[]", "title", "Goodbye World", :id => nil)
+ assert_dom_equal(
+ %{<input name="post[#{pid}][title]" type="radio" value="Goodbye World" />},
+ radio_button("post[]", "title", "Goodbye World", id: nil)
)
end
def test_form_for_requires_block
assert_raises(ArgumentError) do
- form_for(:post, @post, :html => { :id => 'create-post' })
+ form_for(:post, @post, html: { id: 'create-post' })
end
end
def test_form_for_requires_arguments
error = assert_raises(ArgumentError) do
- form_for(nil, :html => { :id => 'create-post' }) do
+ form_for(nil, html: { id: 'create-post' }) do
end
end
assert_equal "First argument in form cannot contain nil or be empty", error.message
error = assert_raises(ArgumentError) do
- form_for([nil, nil], :html => { :id => 'create-post' }) do
+ form_for([nil, nil], html: { id: 'create-post' }) do
end
end
assert_equal "First argument in form cannot contain nil or be empty", error.message
end
def test_form_for
- form_for(@post, :html => { :id => 'create-post' }) do |f|
+ form_for(@post, html: { id: 'create-post' }) do |f|
concat f.label(:title) { "The Title" }
concat f.text_field(:title)
concat f.text_area(:body)
@@ -1089,7 +1168,7 @@ class FormHelperTest < ActionView::TestCase
}
end
- expected = whole_form("/posts/123", "create-post" , "edit_post", :method => 'patch') do
+ expected = whole_form("/posts/123", "create-post", "edit_post", method: "patch") do
"<label for='post_title'>The Title</label>" +
"<input name='post[title]' type='text' id='post_title' value='Hello World' />" +
"<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" +
@@ -1110,7 +1189,7 @@ class FormHelperTest < ActionView::TestCase
concat f.collection_radio_buttons(:active, [true, false], :to_s, :to_s)
end
- expected = whole_form("/posts", "new_post" , "new_post") do
+ expected = whole_form("/posts", "new_post", "new_post") do
"<input id='post_active_true' name='post[active]' type='radio' value='true' />" +
"<label for='post_active_true'>true</label>" +
"<input checked='checked' id='post_active_false' name='post[active]' type='radio' value='false' />" +
@@ -1123,6 +1202,7 @@ class FormHelperTest < ActionView::TestCase
def test_form_for_with_collection_radio_buttons_with_custom_builder_block
post = Post.new
def post.active; false; end
+
form_for(post) do |f|
rendered_radio_buttons = f.collection_radio_buttons(:active, [true, false], :to_s, :to_s) do |b|
b.label { b.radio_button + b.text }
@@ -1130,7 +1210,7 @@ class FormHelperTest < ActionView::TestCase
concat rendered_radio_buttons
end
- expected = whole_form("/posts", "new_post" , "new_post") do
+ expected = whole_form("/posts", "new_post", "new_post") do
"<label for='post_active_true'>"+
"<input id='post_active_true' name='post[active]' type='radio' value='true' />" +
"true</label>" +
@@ -1142,15 +1222,41 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal expected, output_buffer
end
+ def test_form_for_with_collection_radio_buttons_with_custom_builder_block_does_not_leak_the_template
+ post = Post.new
+ def post.active; false; end
+ def post.id; 1; end
+
+ form_for(post) do |f|
+ rendered_radio_buttons = f.collection_radio_buttons(:active, [true, false], :to_s, :to_s) do |b|
+ b.label { b.radio_button + b.text }
+ end
+ concat rendered_radio_buttons
+ concat f.hidden_field :id
+ end
+
+ expected = whole_form("/posts", "new_post_1", "new_post") do
+ "<label for='post_active_true'>"+
+ "<input id='post_active_true' name='post[active]' type='radio' value='true' />" +
+ "true</label>" +
+ "<label for='post_active_false'>"+
+ "<input checked='checked' id='post_active_false' name='post[active]' type='radio' value='false' />" +
+ "false</label>"+
+ "<input id='post_id' name='post[id]' type='hidden' value='1' />"
+ end
+
+ assert_dom_equal expected, output_buffer
+ end
+
def test_form_for_with_collection_check_boxes
post = Post.new
def post.tag_ids; [1, 3]; end
- collection = (1..3).map{|i| [i, "Tag #{i}"] }
+ collection = (1..3).map { |i| [i, "Tag #{i}"] }
form_for(post) do |f|
concat f.collection_check_boxes(:tag_ids, collection, :first, :last)
end
- expected = whole_form("/posts", "new_post" , "new_post") do
+ expected = whole_form("/posts", "new_post", "new_post") do
"<input checked='checked' id='post_tag_ids_1' name='post[tag_ids][]' type='checkbox' value='1' />" +
"<label for='post_tag_ids_1'>Tag 1</label>" +
"<input id='post_tag_ids_2' name='post[tag_ids][]' type='checkbox' value='2' />" +
@@ -1166,7 +1272,7 @@ class FormHelperTest < ActionView::TestCase
def test_form_for_with_collection_check_boxes_with_custom_builder_block
post = Post.new
def post.tag_ids; [1, 3]; end
- collection = (1..3).map{|i| [i, "Tag #{i}"] }
+ collection = (1..3).map { |i| [i, "Tag #{i}"] }
form_for(post) do |f|
rendered_check_boxes = f.collection_check_boxes(:tag_ids, collection, :first, :last) do |b|
b.label { b.check_box + b.text }
@@ -1174,7 +1280,7 @@ class FormHelperTest < ActionView::TestCase
concat rendered_check_boxes
end
- expected = whole_form("/posts", "new_post" , "new_post") do
+ expected = whole_form("/posts", "new_post", "new_post") do
"<label for='post_tag_ids_1'>" +
"<input checked='checked' id='post_tag_ids_1' name='post[tag_ids][]' type='checkbox' value='1' />" +
"Tag 1</label>" +
@@ -1190,14 +1296,45 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal expected, output_buffer
end
+ def test_form_for_with_collection_check_boxes_with_custom_builder_block_does_not_leak_the_template
+ post = Post.new
+ def post.tag_ids; [1, 3]; end
+ def post.id; 1; end
+ collection = (1..3).map { |i| [i, "Tag #{i}"] }
+
+ form_for(post) do |f|
+ rendered_check_boxes = f.collection_check_boxes(:tag_ids, collection, :first, :last) do |b|
+ b.label { b.check_box + b.text }
+ end
+ concat rendered_check_boxes
+ concat f.hidden_field :id
+ end
+
+ expected = whole_form("/posts", "new_post_1", "new_post") do
+ "<label for='post_tag_ids_1'>" +
+ "<input checked='checked' id='post_tag_ids_1' name='post[tag_ids][]' type='checkbox' value='1' />" +
+ "Tag 1</label>" +
+ "<label for='post_tag_ids_2'>" +
+ "<input id='post_tag_ids_2' name='post[tag_ids][]' type='checkbox' value='2' />" +
+ "Tag 2</label>" +
+ "<label for='post_tag_ids_3'>" +
+ "<input checked='checked' id='post_tag_ids_3' name='post[tag_ids][]' type='checkbox' value='3' />" +
+ "Tag 3</label>" +
+ "<input name='post[tag_ids][]' type='hidden' value='' />"+
+ "<input id='post_id' name='post[id]' type='hidden' value='1' />"
+ end
+
+ assert_dom_equal expected, output_buffer
+ end
+
def test_form_for_with_file_field_generate_multipart
Post.send :attr_accessor, :file
- form_for(@post, :html => { :id => 'create-post' }) do |f|
+ form_for(@post, html: { id: 'create-post' }) do |f|
concat f.file_field(:file)
end
- expected = whole_form("/posts/123", "create-post" , "edit_post", :method => 'patch', :multipart => true) do
+ expected = whole_form("/posts/123", "create-post", "edit_post", method: "patch", multipart: true) do
"<input name='post[file]' type='file' id='post_file' />"
end
@@ -1213,7 +1350,7 @@ class FormHelperTest < ActionView::TestCase
}
end
- expected = whole_form("/posts/123", "edit_post_123" , "edit_post", :method => 'patch', :multipart => true) do
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch", multipart: true) do
"<input name='post[comment][file]' type='file' id='post_comment_file' />"
end
@@ -1221,11 +1358,11 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_with_format
- form_for(@post, :format => :json, :html => { :id => "edit_post_123", :class => "edit_post" }) do |f|
+ form_for(@post, format: :json, html: { id: "edit_post_123", class: "edit_post" }) do |f|
concat f.label(:title)
end
- expected = whole_form("/posts/123.json", "edit_post_123" , "edit_post", :method => 'patch') do
+ expected = whole_form("/posts/123.json", "edit_post_123", "edit_post", method: 'patch') do
"<label for='post_title'>Title</label>"
end
@@ -1240,7 +1377,7 @@ class FormHelperTest < ActionView::TestCase
concat f.submit('Edit post')
end
- expected = whole_form("/posts/44", "edit_post_44" , "edit_post", :method => 'patch') do
+ expected = whole_form("/posts/44", "edit_post_44", "edit_post", method: "patch") do
"<input name='post[title]' type='text' id='post_title' value='And his name will be forty and four.' />" +
"<input name='commit' type='submit' value='Edit post' />"
end
@@ -1249,15 +1386,15 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_with_symbol_object_name
- form_for(@post, :as => "other_name", :html => { :id => 'create-post' }) do |f|
- concat f.label(:title, :class => 'post_title')
+ form_for(@post, as: "other_name", html: { id: "create-post" }) do |f|
+ concat f.label(:title, class: 'post_title')
concat f.text_field(:title)
concat f.text_area(:body)
concat f.check_box(:secret)
concat f.submit('Create post')
end
- expected = whole_form("/posts/123", "create-post", "edit_other_name", :method => 'patch') do
+ expected = whole_form("/posts/123", "create-post", "edit_other_name", method: "patch") do
"<label for='other_name_title' class='post_title'>Title</label>" +
"<input name='other_name[title]' id='other_name_title' value='Hello World' type='text' />" +
"<textarea name='other_name[body]' id='other_name_body'>\nBack to the hill and over it again!</textarea>" +
@@ -1270,13 +1407,13 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_with_method_as_part_of_html_options
- form_for(@post, :url => '/', :html => { :id => 'create-post', :method => :delete }) do |f|
+ form_for(@post, url: '/', html: { id: 'create-post', method: :delete }) do |f|
concat f.text_field(:title)
concat f.text_area(:body)
concat f.check_box(:secret)
end
- expected = whole_form("/", "create-post", "edit_post", "delete") do
+ expected = whole_form("/", "create-post", "edit_post", method: "delete") do
"<input name='post[title]' type='text' id='post_title' value='Hello World' />" +
"<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" +
"<input name='post[secret]' type='hidden' value='0' />" +
@@ -1287,13 +1424,13 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_with_method
- form_for(@post, :url => '/', :method => :delete, :html => { :id => 'create-post' }) do |f|
+ form_for(@post, url: '/', method: :delete, html: { id: 'create-post' }) do |f|
concat f.text_field(:title)
concat f.text_area(:body)
concat f.check_box(:secret)
end
- expected = whole_form("/", "create-post", "edit_post", "delete") do
+ expected = whole_form("/", "create-post", "edit_post", method: "delete") do
"<input name='post[title]' type='text' id='post_title' value='Hello World' />" +
"<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" +
"<input name='post[secret]' type='hidden' value='0' />" +
@@ -1306,11 +1443,11 @@ class FormHelperTest < ActionView::TestCase
def test_form_for_with_search_field
# Test case for bug which would emit an "object" attribute
# when used with form_for using a search_field form helper
- form_for(Post.new, :url => "/search", :html => { :id => 'search-post', :method => :get}) do |f|
+ form_for(Post.new, url: "/search", html: { id: "search-post", method: :get }) do |f|
concat f.search_field(:title)
end
- expected = whole_form("/search", "search-post", "new_post", "get") do
+ expected = whole_form("/search", "search-post", "new_post", method: "get") do
"<input name='post[title]' type='search' id='post_title' />"
end
@@ -1318,13 +1455,13 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_with_remote
- form_for(@post, :url => '/', :remote => true, :html => { :id => 'create-post', :method => :patch}) do |f|
+ form_for(@post, url: '/', remote: true, html: { id: 'create-post', method: :patch }) do |f|
concat f.text_field(:title)
concat f.text_area(:body)
concat f.check_box(:secret)
end
- expected = whole_form("/", "create-post", "edit_post", :method => 'patch', :remote => true) do
+ expected = whole_form("/", "create-post", "edit_post", method: "patch", remote: true) do
"<input name='post[title]' type='text' id='post_title' value='Hello World' />" +
"<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" +
"<input name='post[secret]' type='hidden' value='0' />" +
@@ -1335,13 +1472,13 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_with_remote_in_html
- form_for(@post, :url => '/', :html => { :remote => true, :id => 'create-post', :method => :patch }) do |f|
+ form_for(@post, url: '/', html: { remote: true, id: 'create-post', method: :patch }) do |f|
concat f.text_field(:title)
concat f.text_area(:body)
concat f.check_box(:secret)
end
- expected = whole_form("/", "create-post", "edit_post", :method => 'patch', :remote => true) do
+ expected = whole_form("/", "create-post", "edit_post", method: "patch", remote: true) do
"<input name='post[title]' type='text' id='post_title' value='Hello World' />" +
"<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" +
"<input name='post[secret]' type='hidden' value='0' />" +
@@ -1354,13 +1491,13 @@ class FormHelperTest < ActionView::TestCase
def test_form_for_with_remote_without_html
@post.persisted = false
@post.stubs(:to_key).returns(nil)
- form_for(@post, :remote => true) do |f|
+ form_for(@post, remote: true) do |f|
concat f.text_field(:title)
concat f.text_area(:body)
concat f.check_box(:secret)
end
- expected = whole_form("/posts", 'new_post', 'new_post', :remote => true) do
+ expected = whole_form("/posts", "new_post", "new_post", remote: true) do
"<input name='post[title]' type='text' id='post_title' value='Hello World' />" +
"<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" +
"<input name='post[secret]' type='hidden' value='0' />" +
@@ -1371,7 +1508,7 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_without_object
- form_for(:post, :html => { :id => 'create-post' }) do |f|
+ form_for(:post, html: { id: 'create-post' }) do |f|
concat f.text_field(:title)
concat f.text_area(:body)
concat f.check_box(:secret)
@@ -1388,14 +1525,14 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_with_index
- form_for(@post, :as => "post[]") do |f|
+ form_for(@post, as: "post[]") do |f|
concat f.label(:title)
concat f.text_field(:title)
concat f.text_area(:body)
concat f.check_box(:secret)
end
- expected = whole_form('/posts/123', 'edit_post[]', 'edit_post[]', 'patch') do
+ expected = whole_form('/posts/123', 'edit_post[]', 'edit_post[]', method: 'patch') do
"<label for='post_123_title'>Title</label>" +
"<input name='post[123][title]' type='text' id='post_123_title' value='Hello World' />" +
"<textarea name='post[123][body]' id='post_123_body'>\nBack to the hill and over it again!</textarea>" +
@@ -1407,13 +1544,13 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_with_nil_index_option_override
- form_for(@post, :as => "post[]", :index => nil) do |f|
+ form_for(@post, as: "post[]", index: nil) do |f|
concat f.text_field(:title)
concat f.text_area(:body)
concat f.check_box(:secret)
end
- expected = whole_form('/posts/123', 'edit_post[]', 'edit_post[]', 'patch') do
+ expected = whole_form('/posts/123', 'edit_post[]', 'edit_post[]', method: 'patch') do
"<input name='post[][title]' type='text' id='post__title' value='Hello World' />" +
"<textarea name='post[][body]' id='post__body'>\nBack to the hill and over it again!</textarea>" +
"<input name='post[][secret]' type='hidden' value='0' />" +
@@ -1425,12 +1562,12 @@ class FormHelperTest < ActionView::TestCase
def test_form_for_label_error_wrapping
form_for(@post) do |f|
- concat f.label(:author_name, :class => 'label')
+ concat f.label(:author_name, class: 'label')
concat f.text_field(:author_name)
concat f.submit('Create post')
end
- expected = whole_form('/posts/123', 'edit_post_123' , 'edit_post', 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
"<div class='field_with_errors'><label for='post_author_name' class='label'>Author name</label></div>" +
"<div class='field_with_errors'><input name='post[author_name]' type='text' id='post_author_name' value='' /></div>" +
"<input name='commit' type='submit' value='Create post' />"
@@ -1443,12 +1580,12 @@ class FormHelperTest < ActionView::TestCase
post = remove_instance_variable :@post
form_for(post) do |f|
- concat f.label(:author_name, :class => 'label')
+ concat f.label(:author_name, class: 'label')
concat f.text_field(:author_name)
concat f.submit('Create post')
end
- expected = whole_form('/posts/123', 'edit_post_123' , 'edit_post', 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
"<div class='field_with_errors'><label for='post_author_name' class='label'>Author name</label></div>" +
"<div class='field_with_errors'><input name='post[author_name]' type='text' id='post_author_name' value='' /></div>" +
"<input name='commit' type='submit' value='Create post' />"
@@ -1459,11 +1596,11 @@ class FormHelperTest < ActionView::TestCase
def test_form_for_label_error_wrapping_block_and_non_block_versions
form_for(@post) do |f|
- concat f.label(:author_name, 'Name', :class => 'label')
- concat f.label(:author_name, :class => 'label') { 'Name' }
+ concat f.label(:author_name, 'Name', class: 'label')
+ concat f.label(:author_name, class: 'label') { 'Name' }
end
- expected = whole_form('/posts/123', 'edit_post_123' , 'edit_post', 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
"<div class='field_with_errors'><label for='post_author_name' class='label'>Name</label></div>" +
"<div class='field_with_errors'><label for='post_author_name' class='label'>Name</label></div>"
end
@@ -1472,13 +1609,13 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_with_namespace
- form_for(@post, :namespace => 'namespace') do |f|
+ form_for(@post, namespace: 'namespace') do |f|
concat f.text_field(:title)
concat f.text_area(:body)
concat f.check_box(:secret)
end
- expected = whole_form('/posts/123', 'namespace_edit_post_123', 'edit_post', 'patch') do
+ expected = whole_form('/posts/123', 'namespace_edit_post_123', 'edit_post', method: 'patch') do
"<input name='post[title]' type='text' id='namespace_post_title' value='Hello World' />" +
"<textarea name='post[body]' id='namespace_post_body'>\nBack to the hill and over it again!</textarea>" +
"<input name='post[secret]' type='hidden' value='0' />" +
@@ -1489,7 +1626,7 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_with_namespace_with_date_select
- form_for(@post, :namespace => 'namespace') do |f|
+ form_for(@post, namespace: 'namespace') do |f|
concat f.date_select(:written_on)
end
@@ -1497,12 +1634,12 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_with_namespace_with_label
- form_for(@post, :namespace => 'namespace') do |f|
+ form_for(@post, namespace: 'namespace') do |f|
concat f.label(:title)
concat f.text_field(:title)
end
- expected = whole_form('/posts/123', 'namespace_edit_post_123', 'edit_post', 'patch') do
+ expected = whole_form('/posts/123', 'namespace_edit_post_123', 'edit_post', method: 'patch') do
"<label for='namespace_post_title'>Title</label>" +
"<input name='post[title]' type='text' id='namespace_post_title' value='Hello World' />"
end
@@ -1511,24 +1648,24 @@ class FormHelperTest < ActionView::TestCase
end
def test_two_form_for_with_namespace
- form_for(@post, :namespace => 'namespace_1') do |f|
+ form_for(@post, namespace: 'namespace_1') do |f|
concat f.label(:title)
concat f.text_field(:title)
end
- expected_1 = whole_form('/posts/123', 'namespace_1_edit_post_123', 'edit_post', 'patch') do
+ expected_1 = whole_form('/posts/123', 'namespace_1_edit_post_123', 'edit_post', method: 'patch') do
"<label for='namespace_1_post_title'>Title</label>" +
"<input name='post[title]' type='text' id='namespace_1_post_title' value='Hello World' />"
end
assert_dom_equal expected_1, output_buffer
- form_for(@post, :namespace => 'namespace_2') do |f|
+ form_for(@post, namespace: 'namespace_2') do |f|
concat f.label(:title)
concat f.text_field(:title)
end
- expected_2 = whole_form('/posts/123', 'namespace_2_edit_post_123', 'edit_post', 'patch') do
+ expected_2 = whole_form('/posts/123', 'namespace_2_edit_post_123', 'edit_post', method: 'patch') do
"<label for='namespace_2_post_title'>Title</label>" +
"<input name='post[title]' type='text' id='namespace_2_post_title' value='Hello World' />"
end
@@ -1538,7 +1675,7 @@ class FormHelperTest < ActionView::TestCase
def test_fields_for_with_namespace
@comment.body = 'Hello World'
- form_for(@post, :namespace => 'namespace') do |f|
+ form_for(@post, namespace: 'namespace') do |f|
concat f.text_field(:title)
concat f.text_area(:body)
concat f.fields_for(@comment) { |c|
@@ -1546,7 +1683,7 @@ class FormHelperTest < ActionView::TestCase
}
end
- expected = whole_form('/posts/123', 'namespace_edit_post_123', 'edit_post', 'patch') do
+ expected = whole_form('/posts/123', 'namespace_edit_post_123', 'edit_post', method: 'patch') do
"<input name='post[title]' type='text' id='namespace_post_title' value='Hello World' />" +
"<textarea name='post[body]' id='namespace_post_body'>\nBack to the hill and over it again!</textarea>" +
"<input name='post[comment][body]' type='text' id='namespace_post_comment_body' value='Hello World' />"
@@ -1580,7 +1717,7 @@ class FormHelperTest < ActionView::TestCase
concat f.submit
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
"<input name='commit' type='submit' value='Confirm Post changes' />"
end
@@ -1593,7 +1730,7 @@ class FormHelperTest < ActionView::TestCase
old_locale, I18n.locale = I18n.locale, :submit
form_for(:post) do |f|
- concat f.submit :class => "extra"
+ concat f.submit class: "extra"
end
expected = whole_form do
@@ -1608,11 +1745,11 @@ class FormHelperTest < ActionView::TestCase
def test_submit_with_object_and_nested_lookup
old_locale, I18n.locale = I18n.locale, :submit
- form_for(@post, :as => :another_post) do |f|
+ form_for(@post, as: :another_post) do |f|
concat f.submit
end
- expected = whole_form('/posts/123', 'edit_another_post', 'edit_another_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_another_post', 'edit_another_post', method: 'patch') do
"<input name='commit' type='submit' value='Update your Post' />"
end
@@ -1629,7 +1766,7 @@ class FormHelperTest < ActionView::TestCase
}
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
"<input name='post[comment][body]' type='text' id='post_comment_body' value='Hello World' />"
end
@@ -1637,14 +1774,14 @@ class FormHelperTest < ActionView::TestCase
end
def test_nested_fields_for_with_nested_collections
- form_for(@post, :as => 'post[]') do |f|
+ form_for(@post, as: 'post[]') do |f|
concat f.text_field(:title)
concat f.fields_for('comment[]', @comment) { |c|
concat c.text_field(:name)
}
end
- expected = whole_form('/posts/123', 'edit_post[]', 'edit_post[]', 'patch') do
+ expected = whole_form('/posts/123', 'edit_post[]', 'edit_post[]', method: 'patch') do
"<input name='post[123][title]' type='text' id='post_123_title' value='Hello World' />" +
"<input name='post[123][comment][][name]' type='text' id='post_123_comment__name' value='new comment' />"
end
@@ -1653,14 +1790,14 @@ class FormHelperTest < ActionView::TestCase
end
def test_nested_fields_for_with_index_and_parent_fields
- form_for(@post, :index => 1) do |c|
+ form_for(@post, index: 1) do |c|
concat c.text_field(:title)
- concat c.fields_for('comment', @comment, :index => 1) { |r|
+ concat c.fields_for('comment', @comment, index: 1) { |r|
concat r.text_field(:name)
}
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
"<input name='post[1][title]' type='text' id='post_1_title' value='Hello World' />" +
"<input name='post[1][comment][1][name]' type='text' id='post_1_comment_1_name' value='new comment' />"
end
@@ -1669,13 +1806,13 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_with_index_and_nested_fields_for
- output_buffer = form_for(@post, :index => 1) do |f|
+ output_buffer = form_for(@post, index: 1) do |f|
concat f.fields_for(:comment, @post) { |c|
concat c.text_field(:title)
}
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
"<input name='post[1][comment][title]' type='text' id='post_1_comment_title' value='Hello World' />"
end
@@ -1683,13 +1820,13 @@ class FormHelperTest < ActionView::TestCase
end
def test_nested_fields_for_with_index_on_both
- form_for(@post, :index => 1) do |f|
- concat f.fields_for(:comment, @post, :index => 5) { |c|
+ form_for(@post, index: 1) do |f|
+ concat f.fields_for(:comment, @post, index: 5) { |c|
concat c.text_field(:title)
}
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
"<input name='post[1][comment][5][title]' type='text' id='post_1_comment_5_title' value='Hello World' />"
end
@@ -1697,13 +1834,13 @@ class FormHelperTest < ActionView::TestCase
end
def test_nested_fields_for_with_auto_index
- form_for(@post, :as => "post[]") do |f|
+ form_for(@post, as: "post[]") do |f|
concat f.fields_for(:comment, @post) { |c|
concat c.text_field(:title)
}
end
- expected = whole_form('/posts/123', 'edit_post[]', 'edit_post[]', 'patch') do
+ expected = whole_form('/posts/123', 'edit_post[]', 'edit_post[]', method: 'patch') do
"<input name='post[123][comment][title]' type='text' id='post_123_comment_title' value='Hello World' />"
end
@@ -1712,12 +1849,12 @@ class FormHelperTest < ActionView::TestCase
def test_nested_fields_for_with_index_radio_button
form_for(@post) do |f|
- concat f.fields_for(:comment, @post, :index => 5) { |c|
+ concat f.fields_for(:comment, @post, index: 5) { |c|
concat c.radio_button(:title, "hello")
}
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
"<input name='post[comment][5][title]' type='radio' id='post_comment_5_title_hello' value='hello' />"
end
@@ -1725,13 +1862,13 @@ class FormHelperTest < ActionView::TestCase
end
def test_nested_fields_for_with_auto_index_on_both
- form_for(@post, :as => "post[]") do |f|
+ form_for(@post, as: "post[]") do |f|
concat f.fields_for("comment[]", @post) { |c|
concat c.text_field(:title)
}
end
- expected = whole_form('/posts/123', 'edit_post[]', 'edit_post[]', 'patch') do
+ expected = whole_form('/posts/123', 'edit_post[]', 'edit_post[]', method: 'patch') do
"<input name='post[123][comment][123][title]' type='text' id='post_123_comment_123_title' value='Hello World' />"
end
@@ -1739,21 +1876,21 @@ class FormHelperTest < ActionView::TestCase
end
def test_nested_fields_for_with_index_and_auto_index
- output_buffer = form_for(@post, :as => "post[]") do |f|
- concat f.fields_for(:comment, @post, :index => 5) { |c|
+ output_buffer = form_for(@post, as: "post[]") do |f|
+ concat f.fields_for(:comment, @post, index: 5) { |c|
concat c.text_field(:title)
}
end
- output_buffer << form_for(@post, :as => :post, :index => 1) do |f|
+ output_buffer << form_for(@post, as: :post, index: 1) do |f|
concat f.fields_for("comment[]", @post) { |c|
concat c.text_field(:title)
}
end
- expected = whole_form('/posts/123', 'edit_post[]', 'edit_post[]', 'patch') do
+ expected = whole_form('/posts/123', 'edit_post[]', 'edit_post[]', method: 'patch') do
"<input name='post[123][comment][5][title]' type='text' id='post_123_comment_5_title' value='Hello World' />"
- end + whole_form('/posts/123', 'edit_post', 'edit_post', 'patch') do
+ end + whole_form('/posts/123', 'edit_post', 'edit_post', method: 'patch') do
"<input name='post[1][comment][123][title]' type='text' id='post_1_comment_123_title' value='Hello World' />"
end
@@ -1770,7 +1907,7 @@ class FormHelperTest < ActionView::TestCase
}
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
'<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
'<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="new author" />'
end
@@ -1797,7 +1934,7 @@ class FormHelperTest < ActionView::TestCase
}
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
'<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
'<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />' +
'<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />'
@@ -1816,7 +1953,7 @@ class FormHelperTest < ActionView::TestCase
}
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
'<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
'<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />' +
'<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />'
@@ -1830,12 +1967,12 @@ class FormHelperTest < ActionView::TestCase
form_for(@post) do |f|
concat f.text_field(:title)
- concat f.fields_for(:author, :include_id => false) { |af|
+ concat f.fields_for(:author, include_id: false) { |af|
af.text_field(:name)
}
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
'<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
'<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />'
end
@@ -1846,14 +1983,14 @@ class FormHelperTest < ActionView::TestCase
def test_nested_fields_for_with_an_existing_record_on_a_nested_attributes_one_to_one_association_with_disabled_hidden_id_inherited
@post.author = Author.new(321)
- form_for(@post, :include_id => false) do |f|
+ form_for(@post, include_id: false) do |f|
concat f.text_field(:title)
concat f.fields_for(:author) { |af|
af.text_field(:name)
}
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
'<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
'<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />'
end
@@ -1864,14 +2001,14 @@ class FormHelperTest < ActionView::TestCase
def test_nested_fields_for_with_an_existing_record_on_a_nested_attributes_one_to_one_association_with_disabled_hidden_id_override
@post.author = Author.new(321)
- form_for(@post, :include_id => false) do |f|
+ form_for(@post, include_id: false) do |f|
concat f.text_field(:title)
- concat f.fields_for(:author, :include_id => true) { |af|
+ concat f.fields_for(:author, include_id: true) { |af|
af.text_field(:name)
}
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
'<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
'<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />' +
'<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />'
@@ -1891,7 +2028,7 @@ class FormHelperTest < ActionView::TestCase
}
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
'<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
'<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
'<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />'
@@ -1912,7 +2049,7 @@ class FormHelperTest < ActionView::TestCase
end
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
'<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' +
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
@@ -1933,13 +2070,13 @@ class FormHelperTest < ActionView::TestCase
concat af.text_field(:name)
}
@post.comments.each do |comment|
- concat f.fields_for(:comments, comment, :include_id => false) { |cf|
+ concat f.fields_for(:comments, comment, include_id: false) { |cf|
concat cf.text_field(:name)
}
end
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
'<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
'<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />' +
'<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
@@ -1954,7 +2091,7 @@ class FormHelperTest < ActionView::TestCase
@post.comments = Array.new(2) { |id| Comment.new(id + 1) }
@post.author = Author.new(321)
- form_for(@post, :include_id => false) do |f|
+ form_for(@post, include_id: false) do |f|
concat f.text_field(:title)
concat f.fields_for(:author) { |af|
concat af.text_field(:name)
@@ -1966,7 +2103,7 @@ class FormHelperTest < ActionView::TestCase
end
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
'<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
'<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />' +
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' +
@@ -1980,9 +2117,9 @@ class FormHelperTest < ActionView::TestCase
@post.comments = Array.new(2) { |id| Comment.new(id + 1) }
@post.author = Author.new(321)
- form_for(@post, :include_id => false) do |f|
+ form_for(@post, include_id: false) do |f|
concat f.text_field(:title)
- concat f.fields_for(:author, :include_id => true) { |af|
+ concat f.fields_for(:author, include_id: true) { |af|
concat af.text_field(:name)
}
@post.comments.each do |comment|
@@ -1992,7 +2129,7 @@ class FormHelperTest < ActionView::TestCase
end
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
'<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
'<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="author #321" />' +
'<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
@@ -2015,7 +2152,7 @@ class FormHelperTest < ActionView::TestCase
end
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
'<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' +
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
@@ -2039,7 +2176,7 @@ class FormHelperTest < ActionView::TestCase
end
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
'<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' +
@@ -2062,7 +2199,7 @@ class FormHelperTest < ActionView::TestCase
end
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
'<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="new comment" />' +
'<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" type="text" value="new comment" />'
@@ -2083,7 +2220,7 @@ class FormHelperTest < ActionView::TestCase
end
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
'<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #321" />' +
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
@@ -2101,7 +2238,7 @@ class FormHelperTest < ActionView::TestCase
end
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
'<input name="post[title]" type="text" id="post_title" value="Hello World" />'
end
@@ -2118,7 +2255,7 @@ class FormHelperTest < ActionView::TestCase
}
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
'<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' +
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
@@ -2139,7 +2276,7 @@ class FormHelperTest < ActionView::TestCase
}
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
'<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' +
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
@@ -2161,7 +2298,7 @@ class FormHelperTest < ActionView::TestCase
}
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
'<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #1" />' +
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
@@ -2184,7 +2321,7 @@ class FormHelperTest < ActionView::TestCase
}
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
'<input name="post[title]" type="text" id="post_title" value="Hello World" />' +
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #321" />' +
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
@@ -2199,12 +2336,12 @@ class FormHelperTest < ActionView::TestCase
@post.comments = []
form_for(@post) do |f|
- concat f.fields_for(:comments, Comment.new(321), :child_index => 'abc') { |cf|
+ concat f.fields_for(:comments, Comment.new(321), child_index: 'abc') { |cf|
concat cf.text_field(:name)
}
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
'<input id="post_comments_attributes_abc_name" name="post[comments_attributes][abc][name]" type="text" value="comment #321" />' +
'<input id="post_comments_attributes_abc_id" name="post[comments_attributes][abc][id]" type="hidden" value="321" />'
end
@@ -2222,12 +2359,12 @@ class FormHelperTest < ActionView::TestCase
@post.comments = FakeAssociationProxy.new
form_for(@post) do |f|
- concat f.fields_for(:comments, Comment.new(321), :child_index => 'abc') { |cf|
+ concat f.fields_for(:comments, Comment.new(321), child_index: 'abc') { |cf|
concat cf.text_field(:name)
}
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
'<input id="post_comments_attributes_abc_name" name="post[comments_attributes][abc][name]" type="text" value="comment #321" />' +
'<input id="post_comments_attributes_abc_id" name="post[comments_attributes][abc][id]" type="hidden" value="321" />'
end
@@ -2279,7 +2416,7 @@ class FormHelperTest < ActionView::TestCase
@post.comments = []
form_for(@post) do |f|
- f.fields_for(:comments, Comment.new(321), :child_index => 'abc') { |cf|
+ f.fields_for(:comments, Comment.new(321), child_index: 'abc') { |cf|
assert_equal cf.index, 'abc'
}
end
@@ -2313,7 +2450,7 @@ class FormHelperTest < ActionView::TestCase
}
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" type="text" value="comment #321" />' +
'<input id="post_comments_attributes_0_relevances_attributes_0_value" name="post[comments_attributes][0][relevances_attributes][0][value]" type="text" value="commentrelevance #314" />' +
'<input id="post_comments_attributes_0_relevances_attributes_0_id" name="post[comments_attributes][0][relevances_attributes][0][id]" type="hidden" value="314" />' +
@@ -2340,7 +2477,7 @@ class FormHelperTest < ActionView::TestCase
}
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
'<input id="post_author_attributes_name" name="post[author_attributes][name]" type="text" value="hash backed author" />'
end
@@ -2380,7 +2517,7 @@ class FormHelperTest < ActionView::TestCase
end
def test_fields_for_with_nil_index_option_override
- output_buffer = fields_for("post[]", @post, :index => nil) do |f|
+ output_buffer = fields_for("post[]", @post, index: nil) do |f|
concat f.text_field(:title)
concat f.text_area(:body)
concat f.check_box(:secret)
@@ -2396,7 +2533,7 @@ class FormHelperTest < ActionView::TestCase
end
def test_fields_for_with_index_option_override
- output_buffer = fields_for("post[]", @post, :index => "abc") do |f|
+ output_buffer = fields_for("post[]", @post, index: "abc") do |f|
concat f.text_field(:title)
concat f.text_area(:body)
concat f.check_box(:secret)
@@ -2455,7 +2592,7 @@ class FormHelperTest < ActionView::TestCase
end
def test_fields_for_object_with_bracketed_name_and_index
- output_buffer = fields_for("author[post]", @post, :index => 1) do |f|
+ output_buffer = fields_for("author[post]", @post, index: 1) do |f|
concat f.label(:title)
concat f.text_field(:title)
end
@@ -2470,7 +2607,7 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_and_fields_for
- form_for(@post, :as => :post, :html => { :id => 'create-post' }) do |post_form|
+ form_for(@post, as: :post, html: { id: 'create-post' }) do |post_form|
concat post_form.text_field(:title)
concat post_form.text_area(:body)
@@ -2479,7 +2616,7 @@ class FormHelperTest < ActionView::TestCase
}
end
- expected = whole_form('/posts/123', 'create-post', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'create-post', 'edit_post', method: 'patch') do
"<input name='post[title]' type='text' id='post_title' value='Hello World' />" +
"<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" +
"<input name='parent_post[secret]' type='hidden' value='0' />" +
@@ -2490,7 +2627,7 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_and_fields_for_with_object
- form_for(@post, :as => :post, :html => { :id => 'create-post' }) do |post_form|
+ form_for(@post, as: :post, html: { id: 'create-post' }) do |post_form|
concat post_form.text_field(:title)
concat post_form.text_area(:body)
@@ -2499,7 +2636,7 @@ class FormHelperTest < ActionView::TestCase
}
end
- expected = whole_form('/posts/123', 'create-post', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'create-post', 'edit_post', method: 'patch') do
"<input name='post[title]' type='text' id='post_title' value='Hello World' />" +
"<textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea>" +
"<input name='post[comment][name]' type='text' id='post_comment_name' value='new comment' />"
@@ -2515,7 +2652,7 @@ class FormHelperTest < ActionView::TestCase
}
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
"<input name='post[category][name]' type='text' id='post_category_name' />"
end
@@ -2533,13 +2670,13 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_with_labelled_builder
- form_for(@post, :builder => LabelledFormBuilder) do |f|
+ form_for(@post, builder: LabelledFormBuilder) do |f|
concat f.text_field(:title)
concat f.text_area(:body)
concat f.check_box(:secret)
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
"<label for='title'>Title:</label> <input name='post[title]' type='text' id='post_title' value='Hello World' /><br/>" +
"<label for='body'>Body:</label> <textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea><br/>" +
"<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' /><br/>"
@@ -2558,7 +2695,7 @@ class FormHelperTest < ActionView::TestCase
concat f.check_box(:secret)
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
"<label for='title'>Title:</label> <input name='post[title]' type='text' id='post_title' value='Hello World' /><br/>" +
"<label for='body'>Body:</label> <textarea name='post[body]' id='post_body'>\nBack to the hill and over it again!</textarea><br/>" +
"<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' /><br/>"
@@ -2577,7 +2714,7 @@ class FormHelperTest < ActionView::TestCase
concat f.text_field(:title)
end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'patch') do
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
"<label for='title'>Title:</label> <input name='post[title]' type='text' id='post_title' value='Hello World' /><br/>"
end
@@ -2587,7 +2724,7 @@ class FormHelperTest < ActionView::TestCase
end
def test_fields_for_with_labelled_builder
- output_buffer = fields_for(:post, @post, :builder => LabelledFormBuilder) do |f|
+ output_buffer = fields_for(:post, @post, builder: LabelledFormBuilder) do |f|
concat f.text_field(:title)
concat f.text_area(:body)
concat f.check_box(:secret)
@@ -2604,7 +2741,7 @@ class FormHelperTest < ActionView::TestCase
def test_form_for_with_labelled_builder_with_nested_fields_for_without_options_hash
klass = nil
- form_for(@post, :builder => LabelledFormBuilder) do |f|
+ form_for(@post, builder: LabelledFormBuilder) do |f|
f.fields_for(:comments, Comment.new) do |nested_fields|
klass = nested_fields.class
''
@@ -2617,8 +2754,8 @@ class FormHelperTest < ActionView::TestCase
def test_form_for_with_labelled_builder_with_nested_fields_for_with_options_hash
klass = nil
- form_for(@post, :builder => LabelledFormBuilder) do |f|
- f.fields_for(:comments, Comment.new, :index => 'foo') do |nested_fields|
+ form_for(@post, builder: LabelledFormBuilder) do |f|
+ f.fields_for(:comments, Comment.new, index: 'foo') do |nested_fields|
klass = nested_fields.class
''
end
@@ -2630,7 +2767,7 @@ class FormHelperTest < ActionView::TestCase
def test_form_for_with_labelled_builder_path
path = nil
- form_for(@post, :builder => LabelledFormBuilder) do |f|
+ form_for(@post, builder: LabelledFormBuilder) do |f|
path = f.to_partial_path
''
end
@@ -2643,8 +2780,8 @@ class FormHelperTest < ActionView::TestCase
def test_form_for_with_labelled_builder_with_nested_fields_for_with_custom_builder
klass = nil
- form_for(@post, :builder => LabelledFormBuilder) do |f|
- f.fields_for(:comments, Comment.new, :builder => LabelledFormBuilderSubclass) do |nested_fields|
+ form_for(@post, builder: LabelledFormBuilder) do |f|
+ f.fields_for(:comments, Comment.new, builder: LabelledFormBuilderSubclass) do |nested_fields|
klass = nested_fields.class
''
end
@@ -2654,36 +2791,36 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_with_html_options_adds_options_to_form_tag
- form_for(@post, :html => {:id => 'some_form', :class => 'some_class'}) do |f| end
- expected = whole_form("/posts/123", "some_form", "some_class", 'patch')
+ form_for(@post, html: { id: 'some_form', class: 'some_class' }) do |f| end
+ expected = whole_form("/posts/123", "some_form", "some_class", method: "patch")
assert_dom_equal expected, output_buffer
end
def test_form_for_with_string_url_option
- form_for(@post, :url => 'http://www.otherdomain.com') do |f| end
+ form_for(@post, url: 'http://www.otherdomain.com') do |f| end
- assert_equal whole_form("http://www.otherdomain.com", 'edit_post_123', 'edit_post', 'patch'), output_buffer
+ assert_equal whole_form("http://www.otherdomain.com", "edit_post_123", "edit_post", method: "patch"), output_buffer
end
def test_form_for_with_hash_url_option
- form_for(@post, :url => {:controller => 'controller', :action => 'action'}) do |f| end
+ form_for(@post, url: { controller: 'controller', action: 'action' }) do |f| 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, :url => @post) do |f| end
+ form_for(@post, url: @post) do |f| end
- expected = whole_form("/posts/123", 'edit_post_123', 'edit_post', 'patch')
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch")
assert_equal expected, output_buffer
end
def test_form_for_with_existing_object
form_for(@post) do |f| end
- expected = whole_form("/posts/123", "edit_post_123", "edit_post", 'patch')
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch")
assert_equal expected, output_buffer
end
@@ -2702,7 +2839,7 @@ class FormHelperTest < ActionView::TestCase
@comment.save
form_for([@post, @comment]) {}
- expected = whole_form(post_comment_path(@post, @comment), "edit_comment_1", "edit_comment", 'patch')
+ expected = whole_form(post_comment_path(@post, @comment), "edit_comment_1", "edit_comment", method: "patch")
assert_dom_equal expected, output_buffer
end
@@ -2717,7 +2854,7 @@ class FormHelperTest < ActionView::TestCase
@comment.save
form_for([:admin, @post, @comment]) {}
- expected = whole_form(admin_post_comment_path(@post, @comment), "edit_comment_1", "edit_comment", 'patch')
+ expected = whole_form(admin_post_comment_path(@post, @comment), "edit_comment_1", "edit_comment", method: "patch")
assert_dom_equal expected, output_buffer
end
@@ -2729,15 +2866,15 @@ class FormHelperTest < ActionView::TestCase
end
def test_form_for_with_existing_object_and_custom_url
- form_for(@post, :url => "/super_posts") do |f| end
+ form_for(@post, url: "/super_posts") do |f| end
- expected = whole_form("/super_posts", "edit_post_123", "edit_post", 'patch')
+ expected = whole_form("/super_posts", "edit_post_123", "edit_post", method: "patch")
assert_equal expected, output_buffer
end
def test_form_for_with_default_method_as_patch
form_for(@post) {}
- expected = whole_form("/posts/123", "edit_post_123", "edit_post", "patch")
+ expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch")
assert_dom_equal expected, output_buffer
end
@@ -2798,14 +2935,10 @@ class FormHelperTest < ActionView::TestCase
txt << %{ method="#{method}">}
end
- def whole_form(action = "/", id = nil, html_class = nil, options = nil)
+ def whole_form(action = "/", id = nil, html_class = nil, options = {})
contents = block_given? ? yield : ""
- if options.is_a?(Hash)
- method, remote, multipart = options.values_at(:method, :remote, :multipart)
- else
- method = options
- end
+ method, remote, multipart = options.values_at(:method, :remote, :multipart)
form_text(action, id, html_class, remote, multipart, method) + hidden_fields(method) + contents + "</form>"
end
diff --git a/actionpack/test/template/javascript_helper_test.rb b/actionpack/test/template/javascript_helper_test.rb
index 56919dc592..1eed8adb62 100644
--- a/actionpack/test/template/javascript_helper_test.rb
+++ b/actionpack/test/template/javascript_helper_test.rb
@@ -27,8 +27,8 @@ class JavaScriptHelperTest < ActionView::TestCase
assert_equal %(This \\"thing\\" is really\\n netos\\'), escape_javascript(%(This "thing" is really\n netos'))
assert_equal %(backslash\\\\test), escape_javascript( %(backslash\\test) )
assert_equal %(dont <\\/close> tags), escape_javascript(%(dont </close> tags))
- assert_equal %(unicode &#x2028; newline), escape_javascript(%(unicode \342\200\250 newline).force_encoding('UTF-8').encode!)
- assert_equal %(unicode &#x2029; newline), escape_javascript(%(unicode \342\200\251 newline).force_encoding('UTF-8').encode!)
+ assert_equal %(unicode &#x2028; newline), escape_javascript(%(unicode \342\200\250 newline).force_encoding(Encoding::UTF_8).encode!)
+ assert_equal %(unicode &#x2029; newline), escape_javascript(%(unicode \342\200\251 newline).force_encoding(Encoding::UTF_8).encode!)
assert_equal %(dont <\\/close> tags), j(%(dont </close> tags))
end
diff --git a/actionpack/test/template/record_tag_helper_test.rb b/actionpack/test/template/record_tag_helper_test.rb
index 9c49438f6a..ab84bccb56 100644
--- a/actionpack/test/template/record_tag_helper_test.rb
+++ b/actionpack/test/template/record_tag_helper_test.rb
@@ -41,6 +41,12 @@ class RecordTagHelperTest < ActionView::TestCase
assert_dom_equal expected, actual
end
+ def test_content_tag_for_with_array_css_class
+ expected = %(<tr class="record_tag_post special odd" id="record_tag_post_45"></tr>)
+ actual = content_tag_for(:tr, @post, class: ["special", "odd"])
+ assert_dom_equal expected, actual
+ end
+
def test_content_tag_for_with_prefix_and_extra_html_options
expected = %(<tr class="archived_record_tag_post special" id="archived_record_tag_post_45" style='background-color: #f0f0f0'></tr>)
actual = content_tag_for(:tr, @post, :archived, class: "special", style: "background-color: #f0f0f0")
diff --git a/actionpack/test/template/test_case_test.rb b/actionpack/test/template/test_case_test.rb
index c7231d9cd5..acd002ce73 100644
--- a/actionpack/test/template/test_case_test.rb
+++ b/actionpack/test/template/test_case_test.rb
@@ -329,6 +329,27 @@ module ActionView
assert_template partial: '_partial', locals: { 'second' => '2' }
end
+ test 'raises descriptive error message when template was not rendered' do
+ controller.controller_path = "test"
+ render(template: "test/hello_world_with_partial")
+ e = assert_raise ActiveSupport::TestCase::Assertion do
+ assert_template partial: 'i_was_never_rendered', locals: { 'did_not' => 'happen' }
+ end
+ assert_match "i_was_never_rendered to be rendered but it was not.", e.message
+ assert_match 'Expected ["/test/partial"] to include "i_was_never_rendered"', e.message
+ end
+
+ test 'specifying locals works when the partial is inside a directory with underline prefix' do
+ controller.controller_path = "test"
+ render(template: 'test/render_partial_inside_directory')
+ assert_template partial: 'test/_directory/_partial_with_locales', locals: { 'name' => 'Jane' }
+ end
+
+ test 'specifying locals works when the partial is inside a directory without underline prefix' do
+ controller.controller_path = "test"
+ render(template: 'test/render_partial_inside_directory')
+ assert_template partial: 'test/_directory/partial_with_locales', locals: { 'name' => 'Jane' }
+ end
end
module AHelperWithInitialize
diff --git a/actionpack/test/template/text_helper_test.rb b/actionpack/test/template/text_helper_test.rb
index 412d13bb2b..1b2234f4e2 100644
--- a/actionpack/test/template/text_helper_test.rb
+++ b/actionpack/test/template/text_helper_test.rb
@@ -95,8 +95,8 @@ class TextHelperTest < ActionView::TestCase
end
def test_truncate_multibyte
- assert_equal "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 ...".force_encoding('UTF-8'),
- truncate("\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 \354\225\204\353\235\274\353\246\254\354\230\244".force_encoding('UTF-8'), :length => 10)
+ assert_equal "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 ...".force_encoding(Encoding::UTF_8),
+ truncate("\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 \354\225\204\353\235\274\353\246\254\354\230\244".force_encoding(Encoding::UTF_8), :length => 10)
end
def test_truncate_does_not_modify_the_options_hash
@@ -293,7 +293,7 @@ class TextHelperTest < ActionView::TestCase
end
def test_excerpt_with_utf8
- assert_equal("...\357\254\203ciency could not be...".force_encoding('UTF-8'), excerpt("That's why e\357\254\203ciency could not be helped".force_encoding('UTF-8'), 'could', :radius => 8))
+ assert_equal("...\357\254\203ciency could not be...".force_encoding(Encoding::UTF_8), excerpt("That's why e\357\254\203ciency could not be helped".force_encoding(Encoding::UTF_8), 'could', :radius => 8))
end
def test_excerpt_does_not_modify_the_options_hash
diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb
index ba65349b6a..5d87c96605 100644
--- a/actionpack/test/template/url_helper_test.rb
+++ b/actionpack/test/template/url_helper_test.rb
@@ -437,6 +437,12 @@ class UrlHelperTest < ActiveSupport::TestCase
ActionDispatch::Request.new(env)
end
+ def test_current_page_with_http_head_method
+ @request = request_for_url("/", :method => :head)
+ assert current_page?(url_hash)
+ assert current_page?("http://www.example.com/")
+ end
+
def test_current_page_with_simple_url
@request = request_for_url("/")
assert current_page?(url_hash)