aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
authorMikel Lindsaar <raasdnil@gmail.com>2009-11-24 21:45:14 +1100
committerMikel Lindsaar <raasdnil@gmail.com>2009-11-24 21:45:14 +1100
commit5f2395041d1578433fa825ed5c6f26a201f2203d (patch)
tree3b78531ae77a2173ad0df1103543bdfea0b1f60f /actionpack
parent3a72923e27195983d37bdb39ef26b29cf03d3483 (diff)
parente62e6d409986cd5c99234689aa49e3162d7b3a59 (diff)
downloadrails-5f2395041d1578433fa825ed5c6f26a201f2203d.tar.gz
rails-5f2395041d1578433fa825ed5c6f26a201f2203d.tar.bz2
rails-5f2395041d1578433fa825ed5c6f26a201f2203d.zip
Merge branch 'master' of git://github.com/rails/rails into rails_master
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/actionpack.gemspec6
-rw-r--r--actionpack/lib/abstract_controller/layouts.rb2
-rw-r--r--actionpack/lib/abstract_controller/rendering_controller.rb6
-rw-r--r--actionpack/lib/action_controller/caching.rb1
-rw-r--r--actionpack/lib/action_controller/metal/request_forgery_protection.rb5
-rw-r--r--actionpack/lib/action_controller/metal/responder.rb44
-rw-r--r--actionpack/lib/action_controller/metal/streaming.rb2
-rw-r--r--actionpack/lib/action_controller/translation.rb4
-rwxr-xr-xactionpack/lib/action_dispatch/http/request.rb6
-rw-r--r--actionpack/lib/action_dispatch/middleware/stack.rb6
-rw-r--r--actionpack/lib/action_dispatch/routing.rb117
-rw-r--r--actionpack/lib/action_dispatch/routing/deprecated_mapper.rb3
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb32
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb71
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions.rb19
-rw-r--r--actionpack/lib/action_view/erb/util.rb1
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb13
-rw-r--r--actionpack/lib/action_view/helpers/translation_helper.rb2
-rw-r--r--actionpack/lib/action_view/test_case.rb1
-rw-r--r--actionpack/test/abstract/layouts_test.rb2
-rw-r--r--actionpack/test/abstract_unit.rb22
-rw-r--r--actionpack/test/controller/filters_test.rb1
-rw-r--r--actionpack/test/controller/mime_responds_test.rb22
-rw-r--r--actionpack/test/controller/new_base/render_action_test.rb2
-rw-r--r--actionpack/test/controller/request_forgery_protection_test.rb20
-rw-r--r--actionpack/test/controller/routing_test.rb108
-rw-r--r--actionpack/test/dispatch/request_test.rb4
-rw-r--r--actionpack/test/dispatch/routing_test.rb52
-rw-r--r--actionpack/test/dispatch/test_request_test.rb2
-rw-r--r--actionpack/test/template/form_helper_test.rb66
-rw-r--r--actionpack/test/template/test_case_test.rb13
-rw-r--r--actionpack/test/template/url_helper_test.rb45
32 files changed, 413 insertions, 287 deletions
diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec
index 1930416358..ccf6bf1e83 100644
--- a/actionpack/actionpack.gemspec
+++ b/actionpack/actionpack.gemspec
@@ -16,8 +16,10 @@ Gem::Specification.new do |s|
s.add_dependency('activesupport', '= 3.0.pre')
s.add_dependency('activemodel', '= 3.0.pre')
- s.add_dependency('rack', '~> 1.0.0')
- s.add_dependency('rack-test', '~> 0.5.0')
+ s.add_dependency('rack', '~> 1.0.1')
+ s.add_dependency('rack-test', '~> 0.5.0')
+ s.add_dependency('rack-mount', '~> 0.2.2')
+ s.add_dependency('erubis', '~> 2.6.5')
s.require_path = 'lib'
s.autorequire = 'action_controller'
diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb
index 1616f8030a..c71cef42b2 100644
--- a/actionpack/lib/abstract_controller/layouts.rb
+++ b/actionpack/lib/abstract_controller/layouts.rb
@@ -100,7 +100,7 @@ module AbstractController
# name, return that string. Otherwise, use the superclass'
# layout (which might also be implied)
def _write_layout_method
- case @_layout
+ case defined?(@_layout) ? @_layout : nil
when String
self.class_eval %{def _layout(details) #{@_layout.inspect} end}
when Symbol
diff --git a/actionpack/lib/abstract_controller/rendering_controller.rb b/actionpack/lib/abstract_controller/rendering_controller.rb
index 0aae2b18e9..7054b9cf26 100644
--- a/actionpack/lib/abstract_controller/rendering_controller.rb
+++ b/actionpack/lib/abstract_controller/rendering_controller.rb
@@ -12,6 +12,12 @@ module AbstractController
self._view_paths ||= ActionView::PathSet.new
end
+ # Initialize controller with nil formats.
+ def initialize(*) #:nodoc:
+ @_formats = nil
+ super
+ end
+
# An instance of a view class. The default view class is ActionView::Base
#
# The view class must have the following methods:
diff --git a/actionpack/lib/action_controller/caching.rb b/actionpack/lib/action_controller/caching.rb
index 083d6328af..3caf759032 100644
--- a/actionpack/lib/action_controller/caching.rb
+++ b/actionpack/lib/action_controller/caching.rb
@@ -26,6 +26,7 @@ module ActionController #:nodoc:
# config.action_controller.cache_store = :file_store, "/path/to/cache/directory"
# config.action_controller.cache_store = :drb_store, "druby://localhost:9192"
# config.action_controller.cache_store = :mem_cache_store, "localhost"
+ # config.action_controller.cache_store = :mem_cache_store, Memcached::Rails.new("localhost:11211")
# config.action_controller.cache_store = MyOwnStore.new("parameter")
module Caching
extend ActiveSupport::Concern
diff --git a/actionpack/lib/action_controller/metal/request_forgery_protection.rb b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
index 113c20a758..173df79ee7 100644
--- a/actionpack/lib/action_controller/metal/request_forgery_protection.rb
+++ b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
@@ -101,6 +101,11 @@ module ActionController #:nodoc:
session[:_csrf_token] ||= ActiveSupport::SecureRandom.base64(32)
end
+ # The form's authenticity parameter. Override to provide your own.
+ def form_authenticity_param
+ params[request_forgery_protection_token]
+ end
+
def protect_against_forgery?
allow_forgery_protection
end
diff --git a/actionpack/lib/action_controller/metal/responder.rb b/actionpack/lib/action_controller/metal/responder.rb
index c6e847ba0f..e8e88e7479 100644
--- a/actionpack/lib/action_controller/metal/responder.rb
+++ b/actionpack/lib/action_controller/metal/responder.rb
@@ -14,12 +14,11 @@ module ActionController #:nodoc:
#
# When a request comes, for example with format :xml, three steps happen:
#
- # 1) respond_with searches for a template at people/index.xml;
+ # 1) responder searches for a template at people/index.xml;
#
- # 2) if the template is not available, it will create a responder, passing
- # the controller and the resource and invoke :to_xml on it;
+ # 2) if the template is not available, it will invoke :to_xml in the given resource;
#
- # 3) if the responder does not respond_to :to_xml, call to_format on it.
+ # 3) if the responder does not respond_to :to_xml, call :to_format on it.
#
# === Builtin HTTP verb semantics
#
@@ -88,14 +87,16 @@ module ActionController #:nodoc:
@resource = resources.is_a?(Array) ? resources.last : resources
@resources = resources
@options = options
+ @action = options.delete(:action)
@default_response = options.delete(:default_response)
end
delegate :head, :render, :redirect_to, :to => :controller
delegate :get?, :post?, :put?, :delete?, :to => :request
- # Undefine :to_json since it's defined on Object
+ # Undefine :to_json and :to_yaml since it's defined on Object
undef_method(:to_json) if method_defined?(:to_json)
+ undef_method(:to_yaml) if method_defined?(:to_yaml)
# Initializes a new responder an invoke the proper format. If the format is
# not defined, call to_format.
@@ -111,14 +112,8 @@ module ActionController #:nodoc:
#
def to_html
default_render
- rescue ActionView::MissingTemplate
- if get?
- raise
- elsif has_errors?
- render :action => default_action
- else
- redirect_to resource_location
- end
+ rescue ActionView::MissingTemplate => e
+ navigation_behavior(e)
end
# All others formats follow the procedure below. First we try to render a
@@ -127,9 +122,26 @@ module ActionController #:nodoc:
#
def to_format
default_render
- rescue ActionView::MissingTemplate
+ rescue ActionView::MissingTemplate => e
raise unless resourceful?
+ api_behavior(e)
+ end
+ protected
+
+ # This is the common behavior for "navigation" requests, like :html, :iphone and so forth.
+ def navigation_behavior(error)
+ if get?
+ raise error
+ elsif has_errors?
+ render :action => default_action
+ else
+ redirect_to resource_location
+ end
+ end
+
+ # This is the common behavior for "API" requests, like :xml and :json.
+ def api_behavior(error)
if get?
display resource
elsif has_errors?
@@ -141,8 +153,6 @@ module ActionController #:nodoc:
end
end
- protected
-
# Checks whether the resource responds to the current format or not.
#
def resourceful?
@@ -194,7 +204,7 @@ module ActionController #:nodoc:
# the verb is post.
#
def default_action
- request.post? ? :new : :edit
+ @action || (request.post? ? :new : :edit)
end
end
end
diff --git a/actionpack/lib/action_controller/metal/streaming.rb b/actionpack/lib/action_controller/metal/streaming.rb
index 4761763a26..43c661bef4 100644
--- a/actionpack/lib/action_controller/metal/streaming.rb
+++ b/actionpack/lib/action_controller/metal/streaming.rb
@@ -1,5 +1,3 @@
-require 'active_support/core_ext/string/bytesize'
-
module ActionController #:nodoc:
# Methods for sending arbitrary data and for streaming files to the browser,
# instead of rendering.
diff --git a/actionpack/lib/action_controller/translation.rb b/actionpack/lib/action_controller/translation.rb
index 9bb63cdb15..65e9eddb0a 100644
--- a/actionpack/lib/action_controller/translation.rb
+++ b/actionpack/lib/action_controller/translation.rb
@@ -1,12 +1,12 @@
module ActionController
module Translation
def translate(*args)
- I18n.translate *args
+ I18n.translate(*args)
end
alias :t :translate
def localize(*args)
- I18n.localize *args
+ I18n.localize(*args)
end
alias :l :localize
end
diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb
index 75be2cc260..6a52854961 100755
--- a/actionpack/lib/action_dispatch/http/request.rb
+++ b/actionpack/lib/action_dispatch/http/request.rb
@@ -5,7 +5,7 @@ require 'strscan'
require 'active_support/memoizable'
require 'active_support/core_ext/array/wrap'
require 'active_support/core_ext/hash/indifferent_access'
-require 'active_support/core_ext/object/tap'
+require 'active_support/core_ext/string/access'
module ActionDispatch
class Request < Rack::Request
@@ -166,7 +166,7 @@ module ActionDispatch
@env["action_dispatch.request.formats"] ||=
if parameters[:format]
- [Mime[parameters[:format]]]
+ Array.wrap(Mime[parameters[:format]])
elsif xhr? || (accept && !accept.include?(?,))
accepts
else
@@ -489,7 +489,7 @@ EOM
def self.extended(object)
object.class_eval do
attr_accessor :original_path, :content_type
- alias_method :local_path, :path
+ alias_method :local_path, :path if method_defined?(:path)
end
end
diff --git a/actionpack/lib/action_dispatch/middleware/stack.rb b/actionpack/lib/action_dispatch/middleware/stack.rb
index 4f71ea6165..3b27309f58 100644
--- a/actionpack/lib/action_dispatch/middleware/stack.rb
+++ b/actionpack/lib/action_dispatch/middleware/stack.rb
@@ -1,3 +1,5 @@
+require "active_support/inflector/methods"
+
module ActionDispatch
class MiddlewareStack < Array
class Middleware
@@ -32,7 +34,7 @@ module ActionDispatch
elsif @klass.respond_to?(:call)
@klass.call
else
- @klass.to_s.constantize
+ ActiveSupport::Inflector.constantize(@klass.to_s)
end
end
@@ -53,7 +55,7 @@ module ActionDispatch
when Class
klass == middleware
else
- klass == middleware.to_s.constantize
+ klass == ActiveSupport::Inflector.constantize(middleware.to_s)
end
end
diff --git a/actionpack/lib/action_dispatch/routing.rb b/actionpack/lib/action_dispatch/routing.rb
index 68ed1e3340..9b977800b4 100644
--- a/actionpack/lib/action_dispatch/routing.rb
+++ b/actionpack/lib/action_dispatch/routing.rb
@@ -264,11 +264,8 @@ module ActionDispatch
autoload :RouteSet, 'action_dispatch/routing/route_set'
SEPARATORS = %w( / . ? )
-
HTTP_METHODS = [:get, :head, :post, :put, :delete, :options]
- ALLOWED_REQUIREMENTS_FOR_OPTIMISATION = [:controller, :action].to_set
-
# The root paths which may contain controller files
mattr_accessor :controller_paths
self.controller_paths = []
@@ -279,46 +276,28 @@ module ActionDispatch
end
class << self
- # Expects an array of controller names as the first argument.
- # Executes the passed block with only the named controllers named available.
- # This method is used in internal Rails testing.
- def with_controllers(names)
- prior_controllers = @possible_controllers
- use_controllers! names
- yield
- ensure
- use_controllers! prior_controllers
+ def controller_constraints
+ @controller_constraints ||= Regexp.union(*possible_controllers.collect { |n| Regexp.escape(n) })
end
- # Returns an array of paths, cleaned of double-slashes and relative path references.
- # * "\\\" and "//" become "\\" or "/".
- # * "/foo/bar/../config" becomes "/foo/config".
- # The returned array is sorted by length, descending.
- def normalize_paths(paths)
- # do the hokey-pokey of path normalization...
- paths = paths.collect do |path|
- path = path.
- gsub("//", "/"). # replace double / chars with a single
- gsub("\\\\", "\\"). # replace double \ chars with a single
- gsub(%r{(.)[\\/]$}, '\1') # drop final / or \ if path ends with it
-
- # eliminate .. paths where possible
- re = %r{[^/\\]+[/\\]\.\.[/\\]}
- path.gsub!(re, "") while path.match(re)
- path
- end
-
- # start with longest path, first
- paths = paths.uniq.sort_by { |path| - path.length }
+ def clear_controller_cache!
+ @controller_constraints = nil
end
- # Returns the array of controller names currently available to ActionController::Routing.
- def possible_controllers
- unless @possible_controllers
- @possible_controllers = []
+ private
+ # Returns the array of controller names currently available to ActionController::Routing.
+ def possible_controllers
+ possible_controllers = []
- paths = controller_paths.select { |path| File.directory?(path) && path != "." }
+ # Find any controller classes already in memory
+ ActionController::Base.subclasses.each do |klass|
+ controller_name = klass.underscore
+ controller_name.gsub!(/_controller\Z/, '')
+ possible_controllers << controller_name
+ end
+ # Find controllers in controllers/ directory
+ paths = controller_paths.select { |path| File.directory?(path) && path != "." }
seen_paths = Hash.new {|h, k| h[k] = true; false}
normalize_paths(paths).each do |load_path|
Dir["#{load_path}/**/*_controller.rb"].collect do |path|
@@ -327,55 +306,37 @@ module ActionDispatch
controller_name = path[(load_path.length + 1)..-1]
controller_name.gsub!(/_controller\.rb\Z/, '')
- @possible_controllers << controller_name
+ possible_controllers << controller_name
end
end
# remove duplicates
- @possible_controllers.uniq!
- end
- @possible_controllers
- end
-
- # Replaces the internal list of controllers available to ActionController::Routing with the passed argument.
- # ActionController::Routing.use_controllers!([ "posts", "comments", "admin/comments" ])
- def use_controllers!(controller_names)
- @possible_controllers = controller_names
- end
+ possible_controllers.uniq!
- # Returns a controller path for a new +controller+ based on a +previous+ controller path.
- # Handles 4 scenarios:
- #
- # * stay in the previous controller:
- # controller_relative_to( nil, "groups/discussion" ) # => "groups/discussion"
- #
- # * stay in the previous namespace:
- # controller_relative_to( "posts", "groups/discussion" ) # => "groups/posts"
- #
- # * forced move to the root namespace:
- # controller_relative_to( "/posts", "groups/discussion" ) # => "posts"
- #
- # * previous namespace is root:
- # controller_relative_to( "posts", "anything_with_no_slashes" ) # =>"posts"
- #
- def controller_relative_to(controller, previous)
- if controller.nil? then previous
- elsif controller[0] == ?/ then controller[1..-1]
- elsif %r{^(.*)/} =~ previous then "#{$1}/#{controller}"
- else controller
+ possible_controllers
end
- end
- end
- ActiveSupport::Inflector.module_eval do
- # Ensures that routes are reloaded when Rails inflections are updated.
- def inflections_with_route_reloading(&block)
- returning(inflections_without_route_reloading(&block)) {
- ActionDispatch::Routing::Routes.reload! if block_given?
- }
- end
+ # Returns an array of paths, cleaned of double-slashes and relative path references.
+ # * "\\\" and "//" become "\\" or "/".
+ # * "/foo/bar/../config" becomes "/foo/config".
+ # The returned array is sorted by length, descending.
+ def normalize_paths(paths)
+ # do the hokey-pokey of path normalization...
+ paths = paths.collect do |path|
+ path = path.
+ gsub("//", "/"). # replace double / chars with a single
+ gsub("\\\\", "\\"). # replace double \ chars with a single
+ gsub(%r{(.)[\\/]$}, '\1') # drop final / or \ if path ends with it
+
+ # eliminate .. paths where possible
+ re = %r{[^/\\]+[/\\]\.\.[/\\]}
+ path.gsub!(re, "") while path.match(re)
+ path
+ end
- alias_method_chain :inflections, :route_reloading
+ # start with longest path, first
+ paths = paths.uniq.sort_by { |path| - path.length }
+ end
end
end
end
diff --git a/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb b/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb
index 0564ba9797..dd76391870 100644
--- a/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb
@@ -113,8 +113,7 @@ module ActionDispatch
end
end
- possible_names = Routing.possible_controllers.collect { |n| Regexp.escape(n) }
- requirements[:controller] ||= Regexp.union(*possible_names)
+ requirements[:controller] ||= Routing.controller_constraints
if defaults[:controller]
defaults[:action] ||= 'index'
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index ebfb4c9be2..cfe7425a61 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -52,30 +52,38 @@ module ActionDispatch
resource = resources.pop
+ plural = resource.to_s
+ singular = plural.singularize
+
if @scope[:scope_level] == :resources
- member do
- resources(resource, options, &block)
+ parent_resource = @scope[:scope_level_options][:name]
+ with_scope_level(:member) do
+ scope(":#{parent_resource}_id", :name_prefix => parent_resource) do
+ resources(resource, options, &block)
+ end
end
return self
end
- plural = resource.to_s
- singular = plural.singularize
+ if @scope[:options] && (prefix = @scope[:options][:name_prefix])
+ plural = "#{prefix}_#{plural}"
+ singular = "#{prefix}_#{singular}"
+ end
controller(resource) do
namespace(resource) do
- with_scope_level(:resources) do
+ with_scope_level(:resources, :name => singular) do
yield if block_given?
member do
- get "", :to => :show, :as => "#{singular}"
+ get "", :to => :show, :as => singular
put "", :to => :update
delete "", :to => :destroy
get "edit", :to => :edit, :as => "edit_#{singular}"
end
collection do
- get "", :to => :index, :as => "#{plural}"
+ get "", :to => :index, :as => plural
post "", :to => :create
get "new", :to => :new, :as => "new_#{singular}"
end
@@ -127,11 +135,13 @@ module ActionDispatch
end
private
- def with_scope_level(kind)
+ def with_scope_level(kind, options = {})
old, @scope[:scope_level] = @scope[:scope_level], kind
+ old_options, @scope[:scope_level_options] = @scope[:scope_level_options], options
yield
ensure
@scope[:scope_level] = old
+ @scope[:scope_level_options] = old_options
end
end
@@ -195,9 +205,9 @@ module ActionDispatch
@constraints.each { |constraint|
if constraint.respond_to?(:matches?) && !constraint.matches?(req)
- return Rack::Mount::Const::EXPECTATION_FAILED_RESPONSE
+ return [417, {}, []]
elsif constraint.respond_to?(:call) && !constraint.call(req)
- return Rack::Mount::Const::EXPECTATION_FAILED_RESPONSE
+ return [417, {}, []]
end
}
@@ -272,6 +282,8 @@ module ActionDispatch
constraints.reject! { |k, v| segment_keys.include?(k.to_s) }
conditions.merge!(constraints)
+ requirements[:controller] ||= Routing.controller_constraints
+
if via = options[:via]
via = Array(via).map { |m| m.to_s.upcase }
conditions[:request_method] = Regexp.union(*via)
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index 28e5b806da..79e15edeaa 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -5,7 +5,7 @@ module ActionDispatch
module Routing
class RouteSet #:nodoc:
NotFound = lambda { |env|
- raise ActionController::RoutingError, "No route matches #{env[::Rack::Mount::Const::PATH_INFO].inspect} with #{env.inspect}"
+ raise ActionController::RoutingError, "No route matches #{env['PATH_INFO'].inspect} with #{env.inspect}"
}
PARAMETERS_KEY = 'action_dispatch.request.path_parameters'
@@ -246,7 +246,9 @@ module ActionDispatch
end
def load!
- Routing.use_controllers!(nil) # Clear the controller cache so we may discover new ones
+ # Clear the controller cache so we may discover new ones
+ Routing.clear_controller_cache!
+
load_routes!
end
@@ -372,7 +374,17 @@ module ActionDispatch
end
recall[:action] = options.delete(:action) if options[:action] == 'index'
- path = _uri(named_route, options, recall)
+ parameterize = lambda { |name, value|
+ if name == :controller
+ value
+ elsif value.is_a?(Array)
+ value.map { |v| Rack::Mount::Utils.escape_uri(v.to_param) }.join('/')
+ else
+ Rack::Mount::Utils.escape_uri(value.to_param)
+ end
+ }
+
+ path = @set.url(named_route, options, recall, :parameterize => parameterize)
if path && method == :generate_extras
uri = URI(path)
extras = uri.query ?
@@ -439,59 +451,6 @@ module ActionDispatch
def extract_request_environment(request)
{ :method => request.method }
end
-
- private
- def _uri(named_route, params, recall)
- params = URISegment.wrap_values(params)
- recall = URISegment.wrap_values(recall)
-
- unless result = @set.generate(:path_info, named_route, params, recall)
- return
- end
-
- uri, params = result
- params.each do |k, v|
- if v._value
- params[k] = v._value
- else
- params.delete(k)
- end
- end
-
- uri << "?#{Rack::Mount::Utils.build_nested_query(params)}" if uri && params.any?
- uri
- end
-
- class URISegment < Struct.new(:_value, :_escape)
- EXCLUDED = [:controller]
-
- def self.wrap_values(hash)
- hash.inject({}) { |h, (k, v)|
- h[k] = new(v, !EXCLUDED.include?(k.to_sym))
- h
- }
- end
-
- extend Forwardable
- def_delegators :_value, :==, :eql?, :hash
-
- def to_param
- @to_param ||= begin
- if _value.is_a?(Array)
- _value.map { |v| _escaped(v) }.join('/')
- else
- _escaped(_value)
- end
- end
- end
- alias_method :to_s, :to_param
-
- private
- def _escaped(value)
- v = value.respond_to?(:to_param) ? value.to_param : value
- _escape ? Rack::Mount::Utils.escape_uri(v) : v.to_s
- end
- end
end
end
end
diff --git a/actionpack/lib/action_dispatch/testing/assertions.rb b/actionpack/lib/action_dispatch/testing/assertions.rb
index 96f08f2355..0e4a92048f 100644
--- a/actionpack/lib/action_dispatch/testing/assertions.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions.rb
@@ -1,8 +1,21 @@
module ActionDispatch
module Assertions
- %w(response selector tag dom routing model).each do |kind|
- require "action_dispatch/testing/assertions/#{kind}"
- include const_get("#{kind.camelize}Assertions")
+ autoload :DomAssertions, 'action_dispatch/testing/assertions/dom'
+ autoload :ModelAssertions, 'action_dispatch/testing/assertions/model'
+ autoload :ResponseAssertions, 'action_dispatch/testing/assertions/response'
+ autoload :RoutingAssertions, 'action_dispatch/testing/assertions/routing'
+ autoload :SelectorAssertions, 'action_dispatch/testing/assertions/selector'
+ autoload :TagAssertions, 'action_dispatch/testing/assertions/tag'
+
+ extend ActiveSupport::Concern
+
+ included do
+ include DomAssertions
+ include ModelAssertions
+ include ResponseAssertions
+ include RoutingAssertions
+ include SelectorAssertions
+ include TagAssertions
end
end
end
diff --git a/actionpack/lib/action_view/erb/util.rb b/actionpack/lib/action_view/erb/util.rb
index f767a5e27e..aef859b3ac 100644
--- a/actionpack/lib/action_view/erb/util.rb
+++ b/actionpack/lib/action_view/erb/util.rb
@@ -23,6 +23,7 @@ class ERB
end
end
+ undef :h
alias h html_escape
module_function :html_escape
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index c46b39fc23..d0c66eda60 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -963,7 +963,7 @@ module ActionView
end
end
- (field_helpers - %w(label check_box radio_button fields_for)).each do |selector|
+ (field_helpers - %w(label check_box radio_button fields_for hidden_field)).each do |selector|
src = <<-end_src
def #{selector}(method, options = {}) # def text_field(method, options = {})
@template.send( # @template.send(
@@ -1022,6 +1022,11 @@ module ActionView
def radio_button(method, tag_value, options = {})
@template.radio_button(@object_name, method, tag_value, objectify_options(options))
end
+
+ def hidden_field(method, options = {})
+ @emitted_hidden_id = true if method == :id
+ @template.hidden_field(@object_name, method, objectify_options(options))
+ end
def error_message_on(method, *args)
@template.error_message_on(@object, method, *args)
@@ -1035,6 +1040,10 @@ module ActionView
@template.submit_tag(value, options.reverse_merge(:id => "#{object_name}_submit"))
end
+ def emitted_hidden_id?
+ @emitted_hidden_id
+ end
+
private
def objectify_options(options)
@default_options.merge(options.merge(:object => @object))
@@ -1069,8 +1078,8 @@ module ActionView
@template.fields_for(name, object, *args, &block)
else
@template.fields_for(name, object, *args) do |builder|
- @template.concat builder.hidden_field(:id)
block.call(builder)
+ @template.concat builder.hidden_field(:id) unless builder.emitted_hidden_id?
end
end
end
diff --git a/actionpack/lib/action_view/helpers/translation_helper.rb b/actionpack/lib/action_view/helpers/translation_helper.rb
index 4aed10f640..564f12c955 100644
--- a/actionpack/lib/action_view/helpers/translation_helper.rb
+++ b/actionpack/lib/action_view/helpers/translation_helper.rb
@@ -21,7 +21,7 @@ module ActionView
# Delegates to I18n.localize with no additional functionality.
def localize(*args)
- I18n.localize *args
+ I18n.localize(*args)
end
alias :l :localize
diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb
index 8beda24aba..86bbad822d 100644
--- a/actionpack/lib/action_view/test_case.rb
+++ b/actionpack/lib/action_view/test_case.rb
@@ -120,6 +120,7 @@ module ActionView
def _view
view = ActionView::Base.new(ActionController::Base.view_paths, _assigns, @controller)
view.class.send :include, _helpers
+ view.output_buffer = self.output_buffer
view
end
diff --git a/actionpack/test/abstract/layouts_test.rb b/actionpack/test/abstract/layouts_test.rb
index 9c29696ad5..ae2f1bf1f2 100644
--- a/actionpack/test/abstract/layouts_test.rb
+++ b/actionpack/test/abstract/layouts_test.rb
@@ -212,7 +212,7 @@ module AbstractControllerTests
end
test "when the layout is specified as a symbol and the method doesn't exist, raise an exception" do
- assert_raises(NoMethodError, /:nilz/) { WithSymbolAndNoMethod.new.process(:index) }
+ assert_raises(NoMethodError) { WithSymbolAndNoMethod.new.process(:index) }
end
test "when the layout is specified as a symbol and the method returns something besides a string/false/nil, raise an exception" do
diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb
index 214d79cd87..9d055da4b9 100644
--- a/actionpack/test/abstract_unit.rb
+++ b/actionpack/test/abstract_unit.rb
@@ -6,17 +6,13 @@ rescue LoadError
$:.unshift "#{root}/activemodel/lib"
end
-$:.unshift(File.dirname(__FILE__) + '/../lib')
+lib = File.expand_path("#{File.dirname(__FILE__)}/../lib")
+$:.unshift(lib) unless $:.include?('lib') || $:.include?(lib)
+
$:.unshift(File.dirname(__FILE__) + '/lib')
$:.unshift(File.dirname(__FILE__) + '/fixtures/helpers')
$:.unshift(File.dirname(__FILE__) + '/fixtures/alternate_helpers')
-begin
- %w( rack rack/test sqlite3 ).each { |lib| require lib }
-rescue LoadError => e
- abort e.message
-end
-
ENV['TMPDIR'] = File.join(File.dirname(__FILE__), 'tmp')
require 'test/unit'
@@ -195,20 +191,8 @@ class ::ApplicationController < ActionController::Base
end
module ActionController
- module Routing
- def self.possible_controllers
- @@possible_controllers ||= []
- end
- end
-
class Base
include ActionController::Testing
-
- def self.inherited(klass)
- name = klass.name.underscore.sub(/_controller$/, '')
- ActionController::Routing.possible_controllers << name unless name.blank?
- super
- end
end
Base.view_paths = FIXTURE_LOAD_PATH
diff --git a/actionpack/test/controller/filters_test.rb b/actionpack/test/controller/filters_test.rb
index 2da97a9d86..8445428e8f 100644
--- a/actionpack/test/controller/filters_test.rb
+++ b/actionpack/test/controller/filters_test.rb
@@ -1,5 +1,4 @@
require 'abstract_unit'
-require 'active_support/core_ext/symbol'
class ActionController::Base
class << self
diff --git a/actionpack/test/controller/mime_responds_test.rb b/actionpack/test/controller/mime_responds_test.rb
index b070f925d4..fee9cf46f9 100644
--- a/actionpack/test/controller/mime_responds_test.rb
+++ b/actionpack/test/controller/mime_responds_test.rb
@@ -501,6 +501,12 @@ class RespondWithController < ActionController::Base
respond_with(Customer.new("david", 13), :responder => responder)
end
+ def using_resource_with_action
+ respond_with(Customer.new("david", 13), :action => :foo) do |format|
+ format.html { raise ActionView::MissingTemplate.new([], "method") }
+ end
+ end
+
protected
def _render_js(js, options)
@@ -715,6 +721,20 @@ class RespondWithControllerTest < ActionController::TestCase
assert_match /<name>jamis<\/name>/, @response.body
end
+ def test_using_resource_with_action
+ @controller.instance_eval do
+ def render(params={})
+ self.response_body = "#{params[:action]} - #{formats}"
+ end
+ end
+
+ errors = { :name => :invalid }
+ Customer.any_instance.stubs(:errors).returns(errors)
+
+ post :using_resource_with_action
+ assert_equal "foo - #{[:html].to_s}", @controller.response_body
+ end
+
def test_clear_respond_to
@controller = InheritedRespondWithController.new
@request.accept = "text/html"
@@ -760,7 +780,7 @@ class RespondWithControllerTest < ActionController::TestCase
assert_equal "Resource name is david", @response.body
end
- def test_using_resource_with_responder
+ def test_using_resource_with_set_responder
RespondWithController.responder = proc { |c, r, o| c.render :text => "Resource name is #{r.first.name}" }
get :using_resource
assert_equal "Resource name is david", @response.body
diff --git a/actionpack/test/controller/new_base/render_action_test.rb b/actionpack/test/controller/new_base/render_action_test.rb
index ecd29c4530..239f68659c 100644
--- a/actionpack/test/controller/new_base/render_action_test.rb
+++ b/actionpack/test/controller/new_base/render_action_test.rb
@@ -86,7 +86,7 @@ module RenderAction
describe "Both <controller_path>.html.erb and application.html.erb are missing"
test "rendering with layout => true" do
- assert_raise(ArgumentError, /no default layout for RenderAction::BasicController in/) do
+ assert_raise(ArgumentError) do
get "/render_action/basic/hello_world_with_layout", {}, "action_dispatch.show_exceptions" => false
end
end
diff --git a/actionpack/test/controller/request_forgery_protection_test.rb b/actionpack/test/controller/request_forgery_protection_test.rb
index 7111796f8d..09003adf73 100644
--- a/actionpack/test/controller/request_forgery_protection_test.rb
+++ b/actionpack/test/controller/request_forgery_protection_test.rb
@@ -18,7 +18,7 @@ module RequestForgeryProtectionActions
def unsafe
render :text => 'pwn'
end
-
+
def rescue_action(e) raise e end
end
@@ -40,6 +40,13 @@ class FreeCookieController < RequestForgeryProtectionController
end
end
+class CustomAuthenticityParamController < RequestForgeryProtectionController
+ def form_authenticity_param
+ 'foobar'
+ end
+end
+
+
# common test methods
module RequestForgeryProtectionTests
@@ -241,3 +248,14 @@ class FreeCookieControllerTest < ActionController::TestCase
end
end
end
+
+class CustomAuthenticityParamControllerTest < ActionController::TestCase
+ def setup
+ ActionController::Base.request_forgery_protection_token = :authenticity_token
+ end
+
+ def test_should_allow_custom_token
+ post :index, :authenticity_token => 'foobar'
+ assert_response :ok
+ end
+end
diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb
index bb0b9247f3..b5effeda40 100644
--- a/actionpack/test/controller/routing_test.rb
+++ b/actionpack/test/controller/routing_test.rb
@@ -51,30 +51,6 @@ class UriReservedCharactersRoutingTest < Test::Unit::TestCase
end
end
-class RoutingTest < Test::Unit::TestCase
- def test_normalize_unix_paths
- load_paths = %w(. config/../app/controllers config/../app//helpers script/../config/../vendor/rails/actionpack/lib vendor/rails/railties/builtin/rails_info app/models lib script/../config/../foo/bar/../../app/models .foo/../.bar foo.bar/../config)
- paths = ActionController::Routing.normalize_paths(load_paths)
- assert_equal %w(vendor/rails/railties/builtin/rails_info vendor/rails/actionpack/lib app/controllers app/helpers app/models config .bar lib .), paths
- end
-
- def test_normalize_windows_paths
- load_paths = %w(. config\\..\\app\\controllers config\\..\\app\\\\helpers script\\..\\config\\..\\vendor\\rails\\actionpack\\lib vendor\\rails\\railties\\builtin\\rails_info app\\models lib script\\..\\config\\..\\foo\\bar\\..\\..\\app\\models .foo\\..\\.bar foo.bar\\..\\config)
- paths = ActionController::Routing.normalize_paths(load_paths)
- assert_equal %w(vendor\\rails\\railties\\builtin\\rails_info vendor\\rails\\actionpack\\lib app\\controllers app\\helpers app\\models config .bar lib .), paths
- end
-
- def test_routing_helper_module
- assert_kind_of Module, ActionController::Routing::Helpers
-
- h = ActionController::Routing::Helpers
- c = Class.new
- assert ! c.ancestors.include?(h)
- ActionController::Routing::Routes.install_helpers c
- assert c.ancestors.include?(h)
- end
-end
-
class MockController
attr_accessor :routes
@@ -1418,6 +1394,7 @@ class RouteSetTest < ActiveSupport::TestCase
:action => 'show',
:requirements => {:name => /(david|jamis)/i}
end
+
url = set.generate({:controller => 'pages', :action => 'show', :name => 'david'})
assert_equal "/page/david", url
assert_raise ActionController::RoutingError do
@@ -1459,13 +1436,16 @@ class RouteSetTest < ActiveSupport::TestCase
jamis #The Deployer
)/x}
end
- url = set.generate({:controller => 'pages', :action => 'show', :name => 'david'})
- assert_equal "/page/david", url
- assert_raise ActionController::RoutingError do
- url = set.generate({:controller => 'pages', :action => 'show', :name => 'davidjamis'})
- end
- assert_raise ActionController::RoutingError do
- url = set.generate({:controller => 'pages', :action => 'show', :name => 'JAMIS'})
+
+ pending do
+ url = set.generate({:controller => 'pages', :action => 'show', :name => 'david'})
+ assert_equal "/page/david", url
+ assert_raise ActionController::RoutingError do
+ url = set.generate({:controller => 'pages', :action => 'show', :name => 'davidjamis'})
+ end
+ assert_raise ActionController::RoutingError do
+ url = set.generate({:controller => 'pages', :action => 'show', :name => 'JAMIS'})
+ end
end
end
@@ -1480,8 +1460,11 @@ class RouteSetTest < ActiveSupport::TestCase
jamis #The Deployer
)/xi}
end
- url = set.generate({:controller => 'pages', :action => 'show', :name => 'JAMIS'})
- assert_equal "/page/JAMIS", url
+
+ pending do
+ url = set.generate({:controller => 'pages', :action => 'show', :name => 'JAMIS'})
+ assert_equal "/page/JAMIS", url
+ end
end
def test_route_requirement_recognize_with_xi_modifiers
@@ -1645,6 +1628,58 @@ class RouteSetTest < ActiveSupport::TestCase
assert_uri_equal '/foo?x=hello+world', default_route_set.generate({:controller => 'foo', :x => 'hello world'})
end
+ def test_generate_with_default_params
+ set.draw do |map|
+ map.connect 'dummy/page/:page', :controller => 'dummy'
+ map.connect 'dummy/dots/page.:page', :controller => 'dummy', :action => 'dots'
+ map.connect 'ibocorp/:page', :controller => 'ibocorp',
+ :requirements => { :page => /\d+/ },
+ :defaults => { :page => 1 }
+
+ map.connect ':controller/:action/:id'
+ end
+
+ pending do
+ assert_equal '/ibocorp', set.generate({:controller => 'ibocorp', :page => 1})
+ end
+ end
+
+ def test_generate_with_optional_params_recalls_last_request
+ set.draw do |map|
+ map.connect "blog/", :controller => "blog", :action => "index"
+
+ map.connect "blog/:year/:month/:day",
+ :controller => "blog",
+ :action => "show_date",
+ :requirements => { :year => /(19|20)\d\d/, :month => /[01]?\d/, :day => /[0-3]?\d/ },
+ :day => nil, :month => nil
+
+ map.connect "blog/show/:id", :controller => "blog", :action => "show", :id => /\d+/
+ map.connect "blog/:controller/:action/:id"
+ map.connect "*anything", :controller => "blog", :action => "unknown_request"
+ end
+
+ assert_equal({:controller => "blog", :action => "index"}, set.recognize_path("/blog"))
+ assert_equal({:controller => "blog", :action => "show", :id => "123"}, set.recognize_path("/blog/show/123"))
+ assert_equal({:controller => "blog", :action => "show_date", :year => "2004"}, set.recognize_path("/blog/2004"))
+ assert_equal({:controller => "blog", :action => "show_date", :year => "2004", :month => "12"}, set.recognize_path("/blog/2004/12"))
+ assert_equal({:controller => "blog", :action => "show_date", :year => "2004", :month => "12", :day => "25"}, set.recognize_path("/blog/2004/12/25"))
+ assert_equal({:controller => "articles", :action => "edit", :id => "123"}, set.recognize_path("/blog/articles/edit/123"))
+ assert_equal({:controller => "articles", :action => "show_stats"}, set.recognize_path("/blog/articles/show_stats"))
+ assert_equal({:controller => "blog", :action => "unknown_request", :anything => ["blog", "wibble"]}, set.recognize_path("/blog/wibble"))
+ assert_equal({:controller => "blog", :action => "unknown_request", :anything => ["junk"]}, set.recognize_path("/junk"))
+
+ last_request = set.recognize_path("/blog/2006/07/28").freeze
+ assert_equal({:controller => "blog", :action => "show_date", :year => "2006", :month => "07", :day => "28"}, last_request)
+ assert_equal("/blog/2006/07/25", set.generate({:day => 25}, last_request))
+ assert_equal("/blog/2005", set.generate({:year => 2005}, last_request))
+ assert_equal("/blog/show/123", set.generate({:action => "show" , :id => 123}, last_request))
+ pending do
+ assert_equal("/blog/2006/07/28", set.generate({:year => 2006}, last_request))
+ end
+ assert_equal("/blog/2006", set.generate({:year => 2006, :month => nil}, last_request))
+ end
+
private
def assert_uri_equal(expected, actual)
assert_equal(sort_query_string_params(expected), sort_query_string_params(actual))
@@ -1703,13 +1738,6 @@ class RouteLoadingTest < Test::Unit::TestCase
2.times { routes.reload! }
end
- def test_adding_inflections_forces_reload
- ActiveSupport::Inflector::Inflections.instance.expects(:uncountable).with('equipment')
- routes.expects(:reload!)
-
- ActiveSupport::Inflector.inflections { |inflect| inflect.uncountable('equipment') }
- end
-
def test_load_with_configuration
routes.configuration_files.clear
routes.add_configuration_file("foobarbaz")
diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb
index 239fda98e0..b62df9a6b2 100644
--- a/actionpack/test/dispatch/request_test.rb
+++ b/actionpack/test/dispatch/request_test.rb
@@ -432,6 +432,10 @@ class RequestTest < ActiveSupport::TestCase
request = stub_request
request.expects(:parameters).at_least_once.returns({ :format => :txt })
assert_equal with_set(Mime::TEXT), request.formats
+
+ request = stub_request
+ request.expects(:parameters).at_least_once.returns({ :format => :unknown })
+ assert request.formats.empty?
end
test "negotiate_mime" do
diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb
index ca07bc7a28..496445fc34 100644
--- a/actionpack/test/dispatch/routing_test.rb
+++ b/actionpack/test/dispatch/routing_test.rb
@@ -212,9 +212,11 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
with_test_routes do
get '/projects/1/involvements'
assert_equal 'involvements#index', @response.body
+ assert_equal '/projects/1/involvements', project_involvements_path(:project_id => '1')
get '/projects/1/involvements/1'
assert_equal 'involvements#show', @response.body
+ assert_equal '/projects/1/involvements/1', project_involvement_path(:project_id => '1', :id => '1')
end
end
@@ -222,6 +224,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
with_test_routes do
get '/projects/1/attachments'
assert_equal 'attachments#index', @response.body
+ assert_equal '/projects/1/attachments', project_attachments_path(:project_id => '1')
end
end
@@ -229,9 +232,14 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
with_test_routes do
get '/projects/1/participants'
assert_equal 'participants#index', @response.body
+ assert_equal '/projects/1/participants', project_participants_path(:project_id => '1')
put '/projects/1/participants/update_all'
assert_equal 'participants#update_all', @response.body
+
+ pending do
+ assert_equal '/projects/1/participants/update_all', update_all_project_participants_path(:project_id => '1')
+ end
end
end
@@ -239,12 +247,19 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
with_test_routes do
get '/projects/1/companies'
assert_equal 'companies#index', @response.body
+ assert_equal '/projects/1/companies', project_companies_path(:project_id => '1')
get '/projects/1/companies/1/people'
assert_equal 'people#index', @response.body
+ pending do
+ assert_equal '/projects/1/companies/1/people', project_company_people_path(:project_id => '1', :company_id => '1')
+ end
get '/projects/1/companies/1/avatar'
assert_equal 'avatars#show', @response.body
+ pending do
+ assert_equal '/projects/1/companies/1/avatar', project_company_avatar_path(:project_id => '1', :company_id => '1')
+ end
end
end
@@ -252,9 +267,13 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
with_test_routes do
get '/projects/1/images'
assert_equal 'images#index', @response.body
+ assert_equal '/projects/1/images', project_images_path(:project_id => '1')
post '/projects/1/images/1/revise'
assert_equal 'images#revise', @response.body
+ pending do
+ assert_equal '/projects/1/images/1/revise', revise_project_image_path(:project_id => '1', :id => '1')
+ end
end
end
@@ -262,21 +281,35 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
with_test_routes do
get '/projects/1/people'
assert_equal 'people#index', @response.body
+ assert_equal '/projects/1/people', project_people_path(:project_id => '1')
get '/projects/1/people/1'
assert_equal 'people#show', @response.body
+ assert_equal '/projects/1/people/1', project_person_path(:project_id => '1', :id => '1')
get '/projects/1/people/1/7a2dec8/avatar'
assert_equal 'avatars#show', @response.body
+ pending do
+ assert_equal '/projects/1/people/1/7a2dec8/avatar', project_person_avatar_path(:project_id => '1', :person_id => '1', :access_token => '7a2dec8')
+ end
put '/projects/1/people/1/accessible_projects'
assert_equal 'people#accessible_projects', @response.body
+ pending do
+ assert_equal '/projects/1/people/1/accessible_projects', accessible_projects_project_person_path(:project_id => '1', :id => '1')
+ end
post '/projects/1/people/1/resend'
assert_equal 'people#resend', @response.body
+ pending do
+ assert_equal '/projects/1/people/1/resend', resend_project_person_path(:project_id => '1', :id => '1')
+ end
post '/projects/1/people/1/generate_new_password'
assert_equal 'people#generate_new_password', @response.body
+ pending do
+ assert_equal '/projects/1/people/1/generate_new_password', generate_new_password_project_person_path(:project_id => '1', :id => '1')
+ end
end
end
@@ -284,24 +317,43 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
with_test_routes do
get '/projects/1/posts'
assert_equal 'posts#index', @response.body
+ assert_equal '/projects/1/posts', project_posts_path(:project_id => '1')
get '/projects/1/posts/archive'
assert_equal 'posts#archive', @response.body
+ pending do
+ assert_equal '/projects/1/posts/archive', archive_project_posts_path(:project_id => '1')
+ end
get '/projects/1/posts/toggle_view'
assert_equal 'posts#toggle_view', @response.body
+ pending do
+ assert_equal '/projects/1/posts/toggle_view', toggle_view_project_posts_path(:project_id => '1')
+ end
post '/projects/1/posts/1/preview'
assert_equal 'posts#preview', @response.body
+ pending do
+ assert_equal '/projects/1/posts/1/preview', preview_project_post_path(:project_id => '1', :id => '1')
+ end
get '/projects/1/posts/1/subscription'
assert_equal 'subscriptions#show', @response.body
+ pending do
+ assert_equal '/projects/1/posts/1/subscription', project_post_subscription_path(:project_id => '1', :post_id => '1')
+ end
get '/projects/1/posts/1/comments'
assert_equal 'comments#index', @response.body
+ pending do
+ assert_equal '/projects/1/posts/1/comments', project_post_comments_path(:project_id => '1', :post_id => '1')
+ end
post '/projects/1/posts/1/comments/preview'
assert_equal 'comments#preview', @response.body
+ pending do
+ assert_equal '/projects/1/posts/1/comments/preview', preview_project_post_comments_path(:project_id => '1', :post_id => '1')
+ end
end
end
diff --git a/actionpack/test/dispatch/test_request_test.rb b/actionpack/test/dispatch/test_request_test.rb
index b2006a0d2f..5da02b2ea6 100644
--- a/actionpack/test/dispatch/test_request_test.rb
+++ b/actionpack/test/dispatch/test_request_test.rb
@@ -5,7 +5,7 @@ class TestRequestTest < ActiveSupport::TestCase
env = ActionDispatch::TestRequest.new.env
assert_equal "GET", env.delete("REQUEST_METHOD")
- assert_equal nil, env.delete("HTTPS")
+ assert_equal "off", env.delete("HTTPS")
assert_equal "http", env.delete("rack.url_scheme")
assert_equal "example.org", env.delete("SERVER_NAME")
assert_equal "80", env.delete("SERVER_PORT")
diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb
index 04c635e770..44734abb18 100644
--- a/actionpack/test/template/form_helper_test.rb
+++ b/actionpack/test/template/form_helper_test.rb
@@ -613,6 +613,26 @@ class FormHelperTest < ActionView::TestCase
expected = '<form action="http://www.example.com" method="post">' +
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
+ '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
+ '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
+ '</form>'
+
+ assert_dom_equal expected, output_buffer
+ end
+
+ def test_nested_fields_for_with_existing_records_on_a_nested_attributes_one_to_one_association_with_explicit_hidden_field_placement
+ @post.author = Author.new(321)
+
+ form_for(:post, @post) do |f|
+ concat f.text_field(:title)
+ f.fields_for(:author) do |af|
+ concat af.hidden_field(:id)
+ concat af.text_field(:name)
+ end
+ end
+
+ expected = '<form action="http://www.example.com" method="post">' +
+ '<input name="post[title]" size="30" 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]" size="30" type="text" value="author #321" />' +
'</form>'
@@ -634,6 +654,30 @@ class FormHelperTest < ActionView::TestCase
expected = '<form action="http://www.example.com" method="post">' +
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
+ '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
+ '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
+ '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
+ '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' +
+ '</form>'
+
+ assert_dom_equal expected, output_buffer
+ end
+
+ def test_nested_fields_for_with_existing_records_on_a_nested_attributes_collection_association_with_explicit_hidden_field_placement
+ @post.comments = Array.new(2) { |id| Comment.new(id + 1) }
+
+ form_for(:post, @post) do |f|
+ concat f.text_field(:title)
+ @post.comments.each do |comment|
+ f.fields_for(:comments, comment) do |cf|
+ concat cf.hidden_field(:id)
+ concat cf.text_field(:name)
+ end
+ end
+ end
+
+ expected = '<form action="http://www.example.com" method="post">' +
+ '<input name="post[title]" size="30" 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]" size="30" type="text" value="comment #1" />' +
'<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' +
@@ -678,8 +722,8 @@ class FormHelperTest < ActionView::TestCase
expected = '<form action="http://www.example.com" method="post">' +
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
+ '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
'<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
'</form>'
@@ -713,10 +757,10 @@ class FormHelperTest < ActionView::TestCase
expected = '<form action="http://www.example.com" method="post">' +
'<input name="post[title]" size="30" 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]" size="30" type="text" value="comment #1" />' +
- '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' +
+ '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
'<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
+ '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' +
'</form>'
assert_dom_equal expected, output_buffer
@@ -736,8 +780,8 @@ class FormHelperTest < ActionView::TestCase
expected = '<form action="http://www.example.com" method="post">' +
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
- '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
+ '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
'<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
'</form>'
@@ -755,8 +799,8 @@ class FormHelperTest < ActionView::TestCase
end
expected = '<form action="http://www.example.com" method="post">' +
- '<input id="post_comments_attributes_abc_id" name="post[comments_attributes][abc][id]" type="hidden" value="321" />' +
'<input id="post_comments_attributes_abc_name" name="post[comments_attributes][abc][name]" size="30" type="text" value="comment #321" />' +
+ '<input id="post_comments_attributes_abc_id" name="post[comments_attributes][abc][id]" type="hidden" value="321" />' +
'</form>'
assert_dom_equal expected, output_buffer
@@ -790,18 +834,18 @@ class FormHelperTest < ActionView::TestCase
end
expected = '<form action="http://www.example.com" method="post">' +
- '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
- '<input id="post_comments_attributes_0_relevances_attributes_0_id" name="post[comments_attributes][0][relevances_attributes][0][id]" type="hidden" value="314" />' +
'<input id="post_comments_attributes_0_relevances_attributes_0_value" name="post[comments_attributes][0][relevances_attributes][0][value]" size="30" type="text" value="commentrelevance #314" />' +
- '<input id="post_tags_attributes_0_id" name="post[tags_attributes][0][id]" type="hidden" value="123" />' +
+ '<input id="post_comments_attributes_0_relevances_attributes_0_id" name="post[comments_attributes][0][relevances_attributes][0][id]" type="hidden" value="314" />' +
+ '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
'<input id="post_tags_attributes_0_value" name="post[tags_attributes][0][value]" size="30" type="text" value="tag #123" />' +
- '<input id="post_tags_attributes_0_relevances_attributes_0_id" name="post[tags_attributes][0][relevances_attributes][0][id]" type="hidden" value="3141" />' +
'<input id="post_tags_attributes_0_relevances_attributes_0_value" name="post[tags_attributes][0][relevances_attributes][0][value]" size="30" type="text" value="tagrelevance #3141" />' +
- '<input id="post_tags_attributes_1_id" name="post[tags_attributes][1][id]" type="hidden" value="456" />' +
+ '<input id="post_tags_attributes_0_relevances_attributes_0_id" name="post[tags_attributes][0][relevances_attributes][0][id]" type="hidden" value="3141" />' +
+ '<input id="post_tags_attributes_0_id" name="post[tags_attributes][0][id]" type="hidden" value="123" />' +
'<input id="post_tags_attributes_1_value" name="post[tags_attributes][1][value]" size="30" type="text" value="tag #456" />' +
- '<input id="post_tags_attributes_1_relevances_attributes_0_id" name="post[tags_attributes][1][relevances_attributes][0][id]" type="hidden" value="31415" />' +
'<input id="post_tags_attributes_1_relevances_attributes_0_value" name="post[tags_attributes][1][relevances_attributes][0][value]" size="30" type="text" value="tagrelevance #31415" />' +
+ '<input id="post_tags_attributes_1_relevances_attributes_0_id" name="post[tags_attributes][1][relevances_attributes][0][id]" type="hidden" value="31415" />' +
+ '<input id="post_tags_attributes_1_id" name="post[tags_attributes][1][id]" type="hidden" value="456" />' +
'</form>'
assert_dom_equal expected, output_buffer
diff --git a/actionpack/test/template/test_case_test.rb b/actionpack/test/template/test_case_test.rb
index ca72c13ffa..05a409d05a 100644
--- a/actionpack/test/template/test_case_test.rb
+++ b/actionpack/test/template/test_case_test.rb
@@ -24,7 +24,7 @@ module ActionView
test_case.class_eval do
test "helpers defined on ActionView::TestCase are available" do
assert test_case.ancestors.include?(ASharedTestHelper)
- assert 'Holla!', from_shared_helper
+ assert_equal 'Holla!', from_shared_helper
end
end
end
@@ -38,10 +38,15 @@ module ActionView
assert_equal 'Eloy', render('developers/developer', :developer => stub(:name => 'Eloy'))
end
+ test "can render a layout with block" do
+ assert_equal "Before (ChrisCruft)\n!\nAfter",
+ render(:layout => "test/layout_for_partial", :locals => {:name => "ChrisCruft"}) {"!"}
+ end
+
helper AnotherTestHelper
test "additional helper classes can be specified as in a controller" do
assert test_case.ancestors.include?(AnotherTestHelper)
- assert 'Howdy!', from_another_helper
+ assert_equal 'Howdy!', from_another_helper
end
end
@@ -58,14 +63,14 @@ module ActionView
helper AnotherTestHelper
test "additional helper classes can be specified as in a controller" do
assert test_case.ancestors.include?(AnotherTestHelper)
- assert 'Howdy!', from_another_helper
+ assert_equal 'Howdy!', from_another_helper
test_case.helper_class.module_eval do
def render_from_helper
from_another_helper
end
end
- assert 'Howdy!', render(:partial => 'test/from_helper')
+ assert_equal 'Howdy!', render(:partial => 'test/from_helper')
end
end
diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb
index bf0b4ad3a7..5c463a4f60 100644
--- a/actionpack/test/template/url_helper_test.rb
+++ b/actionpack/test/template/url_helper_test.rb
@@ -391,54 +391,47 @@ class UrlHelperTest < ActionView::TestCase
end
end
-class UrlHelperController < ActionController::Base
- def self.controller_path; 'url_helper_with_controller' end
+class UrlHelperControllerTest < ActionController::TestCase
+ class UrlHelperController < ActionController::Base
+ def show_url_for
+ render :inline => "<%= url_for :controller => 'url_helper_controller_test/url_helper', :action => 'show_url_for' %>"
+ end
- def show_url_for
- render :inline => "<%= url_for :controller => 'url_helper_with_controller', :action => 'show_url_for' %>"
- end
+ def show_named_route
+ render :inline => "<%= show_named_route_#{params[:kind]} %>"
+ end
- def show_named_route
- render :inline => "<%= show_named_route_#{params[:kind]} %>"
- end
+ def nil_url_for
+ render :inline => '<%= url_for(nil) %>'
+ end
- def nil_url_for
- render :inline => '<%= url_for(nil) %>'
+ def rescue_action(e) raise e end
end
- def rescue_action(e) raise e end
-end
-
-class UrlHelperWithControllerTest < ActionController::TestCase
- def setup
- super
- @request = ActionController::TestRequest.new
- @response = ActionController::TestResponse.new
- @controller = UrlHelperController.new
- end
+ tests UrlHelperController
def test_url_for_shows_only_path
get :show_url_for
- assert_equal '/url_helper_with_controller/show_url_for', @response.body
+ assert_equal '/url_helper_controller_test/url_helper/show_url_for', @response.body
end
def test_named_route_url_shows_host_and_path
with_url_helper_routing do
get :show_named_route, :kind => 'url'
- assert_equal 'http://test.host/url_helper_with_controller/show_named_route', @response.body
+ assert_equal 'http://test.host/url_helper_controller_test/url_helper/show_named_route', @response.body
end
end
def test_named_route_path_shows_only_path
with_url_helper_routing do
get :show_named_route, :kind => 'path'
- assert_equal '/url_helper_with_controller/show_named_route', @response.body
+ assert_equal '/url_helper_controller_test/url_helper/show_named_route', @response.body
end
end
def test_url_for_nil_returns_current_path
get :nil_url_for
- assert_equal '/url_helper/nil_url_for', @response.body
+ assert_equal '/url_helper_controller_test/url_helper/nil_url_for', @response.body
end
def test_named_route_should_show_host_and_path_using_controller_default_url_options
@@ -450,7 +443,7 @@ class UrlHelperWithControllerTest < ActionController::TestCase
with_url_helper_routing do
get :show_named_route, :kind => 'url'
- assert_equal 'http://testtwo.host/url_helper_with_controller/show_named_route', @response.body
+ assert_equal 'http://testtwo.host/url_helper_controller_test/url_helper/show_named_route', @response.body
end
end
@@ -458,7 +451,7 @@ class UrlHelperWithControllerTest < ActionController::TestCase
def with_url_helper_routing
with_routing do |set|
set.draw do |map|
- map.show_named_route 'url_helper_with_controller/show_named_route', :controller => 'url_helper', :action => 'show_named_route'
+ map.show_named_route 'url_helper_controller_test/url_helper/show_named_route', :controller => 'url_helper_controller_test/url_helper', :action => 'show_named_route'
end
yield
end