aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/CHANGELOG2
-rw-r--r--actionpack/Rakefile3
-rw-r--r--actionpack/actionpack.gemspec2
-rw-r--r--actionpack/lib/action_controller/metal/conditional_get.rb4
-rw-r--r--actionpack/lib/action_controller/metal/head.rb2
-rw-r--r--actionpack/lib/action_controller/metal/http_authentication.rb11
-rw-r--r--actionpack/lib/action_controller/vendor/html-scanner/html/node.rb12
-rw-r--r--actionpack/lib/action_dispatch/http/upload.rb49
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb4
-rw-r--r--actionpack/lib/action_dispatch/routing/route.rb6
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb23
-rw-r--r--actionpack/lib/action_dispatch/testing/integration.rb6
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb76
-rw-r--r--actionpack/lib/action_view/test_case.rb6
-rw-r--r--actionpack/test/controller/assert_select_test.rb18
-rw-r--r--actionpack/test/controller/caching_test.rb10
-rw-r--r--actionpack/test/controller/render_test.rb11
-rw-r--r--actionpack/test/dispatch/routing_test.rb65
-rw-r--r--actionpack/test/template/asset_tag_helper_test.rb16
-rw-r--r--actionpack/test/template/form_helper_test.rb45
21 files changed, 252 insertions, 121 deletions
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG
index 0ec42cc6de..6f8314109b 100644
--- a/actionpack/CHANGELOG
+++ b/actionpack/CHANGELOG
@@ -1,5 +1,7 @@
*Rails 3.1.0 (unreleased)*
+* file_field automatically adds :multipart => true to the enclosing form. [Santiago Pastorino]
+
* Renames csrf_meta_tag -> csrf_meta_tags, and aliases csrf_meta_tag for backwards compatibility. [fxn]
* Add Rack::Cache to the default stack. Create a Rails store that delegates to the Rails cache, so by default, whatever caching layer you are using will be used
diff --git a/actionpack/Rakefile b/actionpack/Rakefile
index d67c6f2410..521ee6913a 100644
--- a/actionpack/Rakefile
+++ b/actionpack/Rakefile
@@ -18,7 +18,8 @@ Rake::TestTask.new(:test_action_pack) do |t|
# this will not happen automatically and the tests (as a whole) will error
t.test_files = Dir.glob('test/{abstract,controller,dispatch,template}/**/*_test.rb').sort
- # t.warning = true
+ #t.warning = true
+ t.verbose = true
end
namespace :test do
diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec
index 75ac47105d..0e91b44914 100644
--- a/actionpack/actionpack.gemspec
+++ b/actionpack/actionpack.gemspec
@@ -26,7 +26,7 @@ Gem::Specification.new do |s|
s.add_dependency('builder', '~> 2.1.2')
s.add_dependency('i18n', '~> 0.4.1')
s.add_dependency('rack', '~> 1.2.1')
- s.add_dependency('rack-test', '~> 0.5.4')
+ s.add_dependency('rack-test', '~> 0.5.5')
s.add_dependency('rack-mount', '~> 0.6.13')
s.add_dependency('tzinfo', '~> 0.3.23')
s.add_dependency('erubis', '~> 2.6.6')
diff --git a/actionpack/lib/action_controller/metal/conditional_get.rb b/actionpack/lib/action_controller/metal/conditional_get.rb
index 797ad846f6..8930c13a68 100644
--- a/actionpack/lib/action_controller/metal/conditional_get.rb
+++ b/actionpack/lib/action_controller/metal/conditional_get.rb
@@ -17,7 +17,7 @@ module ActionController
#
# def show
# @article = Article.find(params[:id])
- # fresh_when(:etag => @article, :last_modified => @article.created_at.utc, :public => true)
+ # fresh_when(:etag => @article, :last_modified => @article.created_at, :public => true)
# end
#
# This will render the show template if the request isn't sending a matching etag or
@@ -48,7 +48,7 @@ module ActionController
# def show
# @article = Article.find(params[:id])
#
- # if stale?(:etag => @article, :last_modified => @article.created_at.utc)
+ # if stale?(:etag => @article, :last_modified => @article.created_at)
# @statistics = @article.really_expensive_call
# respond_to do |format|
# # all the supported formats
diff --git a/actionpack/lib/action_controller/metal/head.rb b/actionpack/lib/action_controller/metal/head.rb
index a5c9910d68..2b4a3b9392 100644
--- a/actionpack/lib/action_controller/metal/head.rb
+++ b/actionpack/lib/action_controller/metal/head.rb
@@ -22,7 +22,7 @@ module ActionController
location = options.delete(:location)
options.each do |key, value|
- headers[key.to_s.dasherize.split(/-/).map { |v| v.capitalize }.join("-")] = value.to_s
+ headers[key.to_s.dasherize.split('-').each { |v| v[0] = v[0].chr.upcase }.join('-')] = value.to_s
end
self.status = status
diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb
index 1d74521e4f..251b1a8a8b 100644
--- a/actionpack/lib/action_controller/metal/http_authentication.rb
+++ b/actionpack/lib/action_controller/metal/http_authentication.rb
@@ -30,7 +30,7 @@ module ActionController
#
#
# === Advanced \Basic example
- #
+ #
# Here is a more advanced \Basic example where only Atom feeds and the XML API is protected by HTTP authentication,
# the regular HTML interface is protected by a session approach:
#
@@ -98,7 +98,7 @@ module ActionController
# end
#
# === Notes
- #
+ #
# The +authenticate_or_request_with_http_digest+ block must return the user's password
# or the ha1 digest hash so the framework can appropriately hash to check the user's
# credentials. Returning +nil+ will cause authentication to fail.
@@ -222,11 +222,10 @@ module ActionController
end
def decode_credentials(header)
- header.to_s.gsub(/^Digest\s+/,'').split(',').inject({}) do |hash, pair|
+ Hash[header.to_s.gsub(/^Digest\s+/,'').split(',').map do |pair|
key, value = pair.split('=', 2)
- hash[key.strip.to_sym] = value.to_s.gsub(/^"|"$/,'').gsub(/'/, '')
- hash
- end
+ [key.strip.to_sym, value.to_s.gsub(/^"|"$/,'').gsub(/'/, '')]
+ end]
end
def authentication_header(controller, realm)
diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb b/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb
index 0eaad2b911..85250721e7 100644
--- a/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb
+++ b/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb
@@ -38,18 +38,14 @@ module HTML #:nodoc:
private
def keys_to_strings(hash)
- hash.keys.inject({}) do |h,k|
- h[k.to_s] = hash[k]
- h
- end
+ Hash[hash.keys.map {|k| [k.to_s, hash[k]]}]
end
def keys_to_symbols(hash)
- hash.keys.inject({}) do |h,k|
+ Hash[hash.keys.map do |k|
raise "illegal key #{k.inspect}" unless k.respond_to?(:to_sym)
- h[k.to_sym] = hash[k]
- h
- end
+ [k.to_sym, hash[k]]
+ end]
end
end
diff --git a/actionpack/lib/action_dispatch/http/upload.rb b/actionpack/lib/action_dispatch/http/upload.rb
index 8ee4b81cdd..49465d820e 100644
--- a/actionpack/lib/action_dispatch/http/upload.rb
+++ b/actionpack/lib/action_dispatch/http/upload.rb
@@ -2,32 +2,27 @@ require 'active_support/core_ext/object/blank'
module ActionDispatch
module Http
- module UploadedFile
- def self.extended(object)
- object.class_eval do
- attr_accessor :original_path, :content_type
- alias_method :local_path, :path if method_defined?(:path)
- end
- end
+ class UploadedFile < Tempfile
+ attr_accessor :original_filename, :content_type, :tempfile, :headers
- # Take the basename of the upload's original filename.
- # This handles the full Windows paths given by Internet Explorer
- # (and perhaps other broken user agents) without affecting
- # those which give the lone filename.
- # The Windows regexp is adapted from Perl's File::Basename.
- def original_filename
- unless defined? @original_filename
- @original_filename =
- unless original_path.blank?
- if original_path =~ /^(?:.*[:\\\/])?(.*)/m
- $1
- else
- File.basename original_path
- end
- end
+ def initialize(hash)
+ @original_filename = hash[:filename]
+ @content_type = hash[:type]
+ @headers = hash[:head]
+
+ # To the untrained eye, this may appear as insanity. Given the alternatives,
+ # such as busting the method cache on every request or breaking backwards
+ # compatibility with is_a?(Tempfile), this solution is the best available
+ # option.
+ #
+ # TODO: Deprecate is_a?(Tempfile) and define a real API for this parameter
+ tempfile = hash[:tempfile]
+ tempfile.instance_variables.each do |ivar|
+ instance_variable_set(ivar, tempfile.instance_variable_get(ivar))
end
- @original_filename
end
+
+ alias local_path path
end
module Upload
@@ -35,11 +30,7 @@ module ActionDispatch
# file upload hash with UploadedFile objects
def normalize_parameters(value)
if Hash === value && value.has_key?(:tempfile)
- upload = value[:tempfile]
- upload.extend(UploadedFile)
- upload.original_path = value[:filename]
- upload.content_type = value[:type]
- upload
+ UploadedFile.new(value)
else
super
end
@@ -47,4 +38,4 @@ module ActionDispatch
private :normalize_parameters
end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index 8a161b0837..fe85acb94e 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -149,6 +149,10 @@ module ActionDispatch
controller = [@scope[:module], controller].compact.join("/").presence
end
+ if controller.is_a?(String) && controller =~ %r{\A/}
+ raise ArgumentError, "controller name should not start with a slash"
+ end
+
controller = controller.to_s unless controller.is_a?(Regexp)
action = action.to_s unless action.is_a?(Regexp)
diff --git a/actionpack/lib/action_dispatch/routing/route.rb b/actionpack/lib/action_dispatch/routing/route.rb
index aefebf8f80..f91a48e16c 100644
--- a/actionpack/lib/action_dispatch/routing/route.rb
+++ b/actionpack/lib/action_dispatch/routing/route.rb
@@ -21,11 +21,7 @@ module ActionDispatch
conditions[:path_info] = ::Rack::Mount::Strexp.compile(path, requirements, SEPARATORS, anchor)
end
- @conditions = conditions.inject({}) { |h, (k, v)|
- h[k] = Rack::Mount::RegexpWithNamedGroups.new(v)
- h
- }
-
+ @conditions = Hash[conditions.map { |k,v| [k, Rack::Mount::RegexpWithNamedGroups.new(v)] }]
@conditions.delete_if{ |k,v| k != :path_info && !valid_condition?(k) }
@requirements.delete_if{ |k,v| !valid_condition?(k) }
end
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index 835ba03784..1a5f21bd09 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -217,27 +217,35 @@ module ActionDispatch
self.valid_conditions.delete(:id)
self.valid_conditions.push(:controller, :action)
+ @append = []
@disable_clear_and_finalize = false
clear!
end
def draw(&block)
clear! unless @disable_clear_and_finalize
+ eval_block(block)
+ finalize! unless @disable_clear_and_finalize
+
+ nil
+ end
+
+ def append(&block)
+ @append << block
+ end
+ def eval_block(block)
mapper = Mapper.new(self)
if default_scope
mapper.with_default_scope(default_scope, &block)
else
mapper.instance_exec(&block)
end
-
- finalize! unless @disable_clear_and_finalize
-
- nil
end
def finalize!
return if @finalized
+ @append.each { |blk| eval_block(blk) }
@finalized = true
@set.freeze
end
@@ -558,13 +566,8 @@ module ActionDispatch
keys = options.delete(:_positional_keys)
keys -= options.keys if args.size < keys.size - 1 # take format into account
- args = args.zip(keys).inject({}) do |h, (v, k)|
- h[k] = v
- h
- end
-
# Tell url_for to skip default_url_options
- options.merge!(args)
+ options.merge!(Hash[args.zip(keys).map { |v, k| [k, v] }])
end
def rewrite_authentication(options)
diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb
index 590ebbf364..a681c9a5b6 100644
--- a/actionpack/lib/action_dispatch/testing/integration.rb
+++ b/actionpack/lib/action_dispatch/testing/integration.rb
@@ -257,17 +257,19 @@ module ActionDispatch
end
end
+ port = host.split(':')[1]
+
env = {
:method => method,
:params => parameters,
"SERVER_NAME" => host.split(':')[0],
- "SERVER_PORT" => (https? ? "443" : "80"),
+ "SERVER_PORT" => (port ? port : (https? ? "443" : "80")),
"HTTPS" => https? ? "on" : "off",
"rack.url_scheme" => https? ? "https" : "http",
"REQUEST_URI" => path,
- "HTTP_HOST" => host,
+ "HTTP_HOST" => [host, port].compact.join(':'),
"REMOTE_ADDR" => remote_addr,
"CONTENT_TYPE" => "application/x-www-form-urlencoded",
"HTTP_ACCEPT" => accept
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
index fdc40c8f2e..687cb83d75 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -827,7 +827,7 @@ module ActionView
def expand_javascript_sources(sources, recursive = false)
if sources.include?(:all)
- all_javascript_files = collect_asset_files(config.javascripts_dir, ('**' if recursive), '*.js')
+ all_javascript_files = (collect_asset_files(config.javascripts_dir, ('**' if recursive), '*.js') - ['application']) << 'application'
((determine_source(:defaults, @@javascript_expansions).dup & all_javascript_files) + all_javascript_files).uniq
else
expanded_sources = sources.collect do |source|
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index 3cc412de63..0937075edf 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -317,8 +317,11 @@ module ActionView
options[:html] ||= {}
options[:html][:remote] = options.delete(:remote)
- output = form_tag(options.delete(:url) || {}, options.delete(:html) || {})
- output << fields_for(object_name, object, options, &proc)
+ builder = options[:parent_builder] = instantiate_builder(object_name, object, options, &proc)
+ fields_for = fields_for(object_name, object, options, &proc)
+ default_options = builder.multipart? ? { :multipart => true } : {}
+ output = form_tag(options.delete(:url) || {}, default_options.merge!(options.delete(:html) || {}))
+ output << fields_for
output.safe_concat('</form>')
end
@@ -339,8 +342,8 @@ module ActionView
options[:html] ||= {}
options[:html].reverse_merge!(html_options)
- options[:url] ||= options[:format] ? \
- polymorphic_path(object_or_array, :format => options.delete(:format)) : \
+ options[:url] ||= options[:format] ?
+ polymorphic_path(object_or_array, :format => options.delete(:format)) :
polymorphic_path(object_or_array)
end
@@ -529,22 +532,7 @@ module ActionView
# <% end %>
# <% end %>
def fields_for(record, record_object = nil, options = nil, &block)
- raise ArgumentError, "Missing block" unless block_given?
-
- options, record_object = record_object, nil if record_object.is_a?(Hash)
- options ||= {}
-
- case record
- when String, Symbol
- object = record_object
- object_name = record
- else
- object = record
- object_name = ActiveModel::Naming.param_key(object)
- end
-
- builder = options[:builder] || ActionView::Base.default_form_builder
- capture(builder.new(object_name, object, self, options, block), &block)
+ capture(instantiate_builder(record, record_object, options, &block), &block)
end
# Returns a label tag tailored for labelling an input field for a specified attribute (identified by +method+) on an object
@@ -850,6 +838,25 @@ module ActionView
def range_field(object_name, method, options = {})
InstanceTag.new(object_name, method, self, options.delete(:object)).to_number_field_tag("range", options)
end
+
+ private
+
+ def instantiate_builder(record, record_object = nil, options = nil, &block)
+ options, record_object = record_object, nil if record_object.is_a?(Hash)
+ options ||= {}
+
+ case record
+ when String, Symbol
+ object = record_object
+ object_name = record
+ else
+ object = record
+ object_name = ActiveModel::Naming.param_key(object)
+ end
+
+ builder = options[:builder] || ActionView::Base.default_form_builder
+ builder.new(object_name, object, self, options, block)
+ end
end
module InstanceTagMethods #:nodoc:
@@ -858,9 +865,9 @@ module ActionView
attr_reader :method_name, :object_name
- DEFAULT_FIELD_OPTIONS = { "size" => 30 }.freeze
- DEFAULT_RADIO_OPTIONS = { }.freeze
- DEFAULT_TEXT_AREA_OPTIONS = { "cols" => 40, "rows" => 20 }.freeze
+ DEFAULT_FIELD_OPTIONS = { "size" => 30 }
+ DEFAULT_RADIO_OPTIONS = { }
+ DEFAULT_TEXT_AREA_OPTIONS = { "cols" => 40, "rows" => 20 }
def initialize(object_name, method_name, template_object, object = nil)
@object_name, @method_name = object_name.to_s.dup, method_name.to_s.dup
@@ -1114,6 +1121,14 @@ module ActionView
attr_accessor :object_name, :object, :options
+ attr_reader :multipart, :parent_builder
+ alias :multipart? :multipart
+
+ def multipart=(multipart)
+ @multipart = multipart
+ parent_builder.multipart = multipart if parent_builder
+ end
+
def self.model_name
@model_name ||= Struct.new(:partial_path).new(name.demodulize.underscore.sub!(/_builder$/, ''))
end
@@ -1125,6 +1140,7 @@ module ActionView
def initialize(object_name, object, template, options, proc)
@nested_child_index = {}
@object_name, @object, @template, @options, @proc = object_name, object, template, options, proc
+ @parent_builder = options[:parent_builder]
@default_options = @options ? @options.slice(:index) : {}
if @object_name.to_s.match(/\[\]$/)
if object ||= @template.instance_variable_get("@#{Regexp.last_match.pre_match}") and object.respond_to?(:to_param)
@@ -1133,9 +1149,10 @@ module ActionView
raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}"
end
end
+ @multipart = nil
end
- (field_helpers - %w(label check_box radio_button fields_for hidden_field)).each do |selector|
+ (field_helpers - %w(label check_box radio_button fields_for hidden_field file_field)).each do |selector|
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
def #{selector}(method, options = {}) # def text_field(method, options = {})
@template.send( # @template.send(
@@ -1157,10 +1174,9 @@ module ActionView
index = ""
end
- if options[:builder]
- args << {} unless args.last.is_a?(Hash)
- args.last[:builder] ||= options[:builder]
- end
+ args << {} unless args.last.is_a?(Hash)
+ args.last[:builder] ||= options[:builder]
+ args.last[:parent_builder] = self
case record_or_name_or_array
when String, Symbol
@@ -1199,6 +1215,10 @@ module ActionView
@template.hidden_field(@object_name, method, objectify_options(options))
end
+ def file_field(method, options = {})
+ self.multipart = true
+ @template.file_field(@object_name, method, objectify_options(options))
+ end
# Add the submit button for the given form. When no value is given, it checks
# if the object is a new resource or not to create the proper label:
#
diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb
index 2c2661df26..ff35fb7df4 100644
--- a/actionpack/lib/action_view/test_case.rb
+++ b/actionpack/lib/action_view/test_case.rb
@@ -189,11 +189,7 @@ module ActionView
end
def _assigns
- _instance_variables.inject({}) do |hash, var|
- name = var[1..-1].to_sym
- hash[name] = instance_variable_get(var)
- hash
- end
+ _instance_variables.map { |var| [var[1..-1].to_sym, instance_variable_get(var)] }
end
def _routes
diff --git a/actionpack/test/controller/assert_select_test.rb b/actionpack/test/controller/assert_select_test.rb
index 2600dae3c5..f63321c78b 100644
--- a/actionpack/test/controller/assert_select_test.rb
+++ b/actionpack/test/controller/assert_select_test.rb
@@ -459,8 +459,8 @@ class AssertSelectTest < ActionController::TestCase
assert_select_rjs :remove, "test1"
- rescue Assertion
- assert_equal "No RJS statement that removes 'test1' was rendered.", $!.message
+ rescue Assertion => e
+ assert_equal "No RJS statement that removes 'test1' was rendered.", e.message
end
def test_assert_select_rjs_for_remove_ignores_block
@@ -491,8 +491,8 @@ class AssertSelectTest < ActionController::TestCase
assert_select_rjs :show, "test1"
- rescue Assertion
- assert_equal "No RJS statement that shows 'test1' was rendered.", $!.message
+ rescue Assertion => e
+ assert_equal "No RJS statement that shows 'test1' was rendered.", e.message
end
def test_assert_select_rjs_for_show_ignores_block
@@ -523,8 +523,8 @@ class AssertSelectTest < ActionController::TestCase
assert_select_rjs :hide, "test1"
- rescue Assertion
- assert_equal "No RJS statement that hides 'test1' was rendered.", $!.message
+ rescue Assertion => e
+ assert_equal "No RJS statement that hides 'test1' was rendered.", e.message
end
def test_assert_select_rjs_for_hide_ignores_block
@@ -555,8 +555,8 @@ class AssertSelectTest < ActionController::TestCase
assert_select_rjs :toggle, "test1"
- rescue Assertion
- assert_equal "No RJS statement that toggles 'test1' was rendered.", $!.message
+ rescue Assertion => e
+ assert_equal "No RJS statement that toggles 'test1' was rendered.", e.message
end
def test_assert_select_rjs_for_toggle_ignores_block
@@ -729,7 +729,7 @@ EOF
end
def render_rjs(&block)
- @controller.response_with &block
+ @controller.response_with(&block)
get :rjs
end
diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb
index 84b796ba72..a83f5155f8 100644
--- a/actionpack/test/controller/caching_test.rb
+++ b/actionpack/test/controller/caching_test.rb
@@ -637,7 +637,7 @@ class FragmentCachingTest < ActionController::TestCase
@store.write('views/another_name', 'another_value')
@store.write('views/primalgrasp', 'will not expire ;-)')
- @controller.expire_fragment /name/
+ @controller.expire_fragment(/name/)
assert_nil @store.read('views/name')
assert_nil @store.read('views/another_name')
@@ -727,22 +727,22 @@ CACHED
def test_fragment_caching_in_partials
get :html_fragment_cached_with_partial
assert_response :success
- assert_match /Old fragment caching in a partial/, @response.body
+ assert_match(/Old fragment caching in a partial/, @response.body)
assert_match "Old fragment caching in a partial", @store.read('views/test.host/functional_caching/html_fragment_cached_with_partial')
end
def test_render_inline_before_fragment_caching
get :inline_fragment_cached
assert_response :success
- assert_match /Some inline content/, @response.body
- assert_match /Some cached content/, @response.body
+ assert_match(/Some inline content/, @response.body)
+ assert_match(/Some cached content/, @response.body)
assert_match "Some cached content", @store.read('views/test.host/functional_caching/inline_fragment_cached')
end
def test_fragment_caching_in_rjs_partials
xhr :get, :js_fragment_cached_with_partial
assert_response :success
- assert_match /Old fragment caching in a partial/, @response.body
+ assert_match(/Old fragment caching in a partial/, @response.body)
assert_match "Old fragment caching in a partial", @store.read('views/test.host/functional_caching/js_fragment_cached_with_partial')
end
diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb
index ab12c0bf17..42723c834e 100644
--- a/actionpack/test/controller/render_test.rb
+++ b/actionpack/test/controller/render_test.rb
@@ -488,6 +488,10 @@ class TestController < ActionController::Base
head :x_custom_header => "something"
end
+ def head_with_www_authenticate_header
+ head 'WWW-Authenticate' => 'something'
+ end
+
def head_with_status_code_first
head :forbidden, :x_custom_header => "something"
end
@@ -1139,6 +1143,13 @@ class RenderTest < ActionController::TestCase
assert_response :ok
end
+ def test_head_with_www_authenticate_header
+ get :head_with_www_authenticate_header
+ assert_blank @response.body
+ assert_equal "something", @response.headers["WWW-Authenticate"]
+ assert_response :ok
+ end
+
def test_head_with_symbolic_status
get :head_with_symbolic_status, :status => "ok"
assert_equal 200, @response.status
diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb
index b642adc06b..3daabf7a64 100644
--- a/actionpack/test/dispatch/routing_test.rb
+++ b/actionpack/test/dispatch/routing_test.rb
@@ -2128,6 +2128,38 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
assert_raises(ActionController::RoutingError){ list_todo_path(:list_id => '2', :id => '1') }
end
+ def test_controller_name_with_leading_slash_raise_error
+ assert_raise(ArgumentError) do
+ self.class.stub_controllers do |routes|
+ routes.draw { get '/feeds/:service', :to => '/feeds#show' }
+ end
+ end
+
+ assert_raise(ArgumentError) do
+ self.class.stub_controllers do |routes|
+ routes.draw { get '/feeds/:service', :controller => '/feeds', :action => 'show' }
+ end
+ end
+
+ assert_raise(ArgumentError) do
+ self.class.stub_controllers do |routes|
+ routes.draw { get '/api/feeds/:service', :to => '/api/feeds#show' }
+ end
+ end
+
+ assert_raise(ArgumentError) do
+ self.class.stub_controllers do |routes|
+ routes.draw { controller("/feeds") { get '/feeds/:service', :to => :show } }
+ end
+ end
+
+ assert_raise(ArgumentError) do
+ self.class.stub_controllers do |routes|
+ routes.draw { resources :feeds, :controller => '/feeds' }
+ end
+ end
+ end
+
private
def with_test_routes
yield
@@ -2152,6 +2184,39 @@ private
end
end
+class TestAppendingRoutes < ActionController::IntegrationTest
+ def simple_app(resp)
+ lambda { |e| [ 200, { 'Content-Type' => 'text/plain' }, [resp] ] }
+ end
+
+ setup do
+ s = self
+ @app = ActionDispatch::Routing::RouteSet.new
+ @app.append do
+ match '/hello' => s.simple_app('fail')
+ match '/goodbye' => s.simple_app('goodbye')
+ end
+
+ @app.draw do
+ match '/hello' => s.simple_app('hello')
+ end
+ end
+
+ def test_goodbye_should_be_available
+ get '/goodbye'
+ assert_equal 'goodbye', @response.body
+ end
+
+ def test_hello_should_not_be_overwritten
+ get '/hello'
+ assert_equal 'hello', @response.body
+ end
+
+ def test_missing_routes_are_still_missing
+ get '/random'
+ assert_equal 404, @response.status
+ end
+end
class TestDefaultScope < ActionController::IntegrationTest
module ::Blog
diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb
index 2b83cfe1a9..ec28d4442c 100644
--- a/actionpack/test/template/asset_tag_helper_test.rb
+++ b/actionpack/test/template/asset_tag_helper_test.rb
@@ -89,8 +89,8 @@ class AssetTagHelperTest < ActionView::TestCase
%(javascript_include_tag("bank", :lang => "vbscript")) => %(<script lang="vbscript" src="/javascripts/bank.js" type="text/javascript"></script>),
%(javascript_include_tag("common.javascript", "/elsewhere/cools")) => %(<script src="/javascripts/common.javascript" type="text/javascript"></script>\n<script src="/elsewhere/cools.js" type="text/javascript"></script>),
%(javascript_include_tag(:defaults)) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/rails.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>),
- %(javascript_include_tag(:all)) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>),
- %(javascript_include_tag(:all, :recursive => true)) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/subdir/subdir.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>),
+ %(javascript_include_tag(:all)) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>),
+ %(javascript_include_tag(:all, :recursive => true)) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/subdir/subdir.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>),
%(javascript_include_tag(:defaults, "bank")) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/rails.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>),
%(javascript_include_tag("bank", :defaults)) => %(<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/rails.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>),
@@ -628,7 +628,7 @@ class AssetTagHelperTest < ActionView::TestCase
assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'combined.js'))
assert_equal(
- %(// prototype js\n\n// effects js\n\n// dragdrop js\n\n// controls js\n\n// application js\n\n// bank js\n\n// robber js\n\n// subdir js\n\n\n// version.1.0 js),
+ %(// prototype js\n\n// effects js\n\n// dragdrop js\n\n// controls js\n\n// bank js\n\n// robber js\n\n// subdir js\n\n\n// version.1.0 js\n\n// application js),
IO.read(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'combined.js'))
)
@@ -649,7 +649,7 @@ class AssetTagHelperTest < ActionView::TestCase
assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'combined.js'))
assert_equal(
- %(// prototype js\n\n// effects js\n\n// dragdrop js\n\n// controls js\n\n// application js\n\n// bank js\n\n// robber js\n\n// version.1.0 js),
+ %(// prototype js\n\n// effects js\n\n// dragdrop js\n\n// controls js\n\n// bank js\n\n// robber js\n\n// version.1.0 js\n\n// application js),
IO.read(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'combined.js'))
)
@@ -686,24 +686,24 @@ class AssetTagHelperTest < ActionView::TestCase
config.perform_caching = false
assert_dom_equal(
- %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>),
+ %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>),
javascript_include_tag(:all, :cache => true)
)
assert_dom_equal(
- %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/subdir/subdir.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>),
+ %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/subdir/subdir.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>),
javascript_include_tag(:all, :cache => true, :recursive => true)
)
assert !File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'all.js'))
assert_dom_equal(
- %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>),
+ %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>),
javascript_include_tag(:all, :cache => "money")
)
assert_dom_equal(
- %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/subdir/subdir.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>),
+ %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/subdir/subdir.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>),
javascript_include_tag(:all, :cache => "money", :recursive => true)
)
diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb
index 97a08d45ba..d40dd409b8 100644
--- a/actionpack/test/template/form_helper_test.rb
+++ b/actionpack/test/template/form_helper_test.rb
@@ -640,6 +640,12 @@ class FormHelperTest < ActionView::TestCase
)
end
+ def test_form_for_requires_block
+ assert_raises(ArgumentError) do
+ form_for(:post, @post, :html => { :id => 'create-post' })
+ end
+ end
+
def test_form_for
assert_deprecated do
form_for(:post, @post, :html => { :id => 'create-post' }) do |f|
@@ -665,6 +671,45 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal expected, output_buffer
end
+ def test_form_for_with_file_field_generate_multipart
+ Post.send :attr_accessor, :file
+
+ assert_deprecated do
+ form_for(:post, @post, :html => { :id => 'create-post' }) do |f|
+ concat f.file_field(:file)
+ end
+ end
+
+ expected =
+ "<form accept-charset='UTF-8' action='/' id='create-post' method='post' enctype='multipart/form-data'>" +
+ snowman +
+ "<input name='post[file]' type='file' id='post_file' />" +
+ "</form>"
+
+ assert_dom_equal expected, output_buffer
+ end
+
+ def test_fields_for_with_file_field_generate_multipart
+ Comment.send :attr_accessor, :file
+
+ assert_deprecated do
+ form_for(:post, @post) do |f|
+ concat f.fields_for(:comment, @post) { |c|
+ concat c.file_field(:file)
+ }
+ end
+ end
+
+ expected =
+ "<form accept-charset='UTF-8' action='/' method='post' enctype='multipart/form-data'>" +
+ snowman +
+ "<input name='post[comment][file]' type='file' id='post_comment_file' />" +
+ "</form>"
+
+ assert_dom_equal expected, output_buffer
+ end
+
+
def test_form_for_with_format
form_for(@post, :format => :json, :html => { :id => "edit_post_123", :class => "edit_post" }) do |f|
concat f.label(:title)