aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
authorGonçalo Silva <goncalossilva@gmail.com>2010-07-10 17:36:10 +0100
committerGonçalo Silva <goncalossilva@gmail.com>2010-07-10 17:36:10 +0100
commitcd2bbed9846d84a1230a1b9e52843eedca17b28d (patch)
tree5214b7855f3d102e4c22239b9d62bc5717cb3547 /actionpack
parentd2c633ba0bfb7baacdee89a46d7d036d24c68817 (diff)
parent80e47d7b88dcc732ebeb5290faab6e529829dac6 (diff)
downloadrails-cd2bbed9846d84a1230a1b9e52843eedca17b28d.tar.gz
rails-cd2bbed9846d84a1230a1b9e52843eedca17b28d.tar.bz2
rails-cd2bbed9846d84a1230a1b9e52843eedca17b28d.zip
Merge branch 'master' of http://github.com/rails/rails
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/actionpack.gemspec2
-rw-r--r--actionpack/lib/abstract_controller/rendering.rb4
-rw-r--r--actionpack/lib/action_controller/base.rb6
-rw-r--r--actionpack/lib/action_controller/metal/helpers.rb5
-rw-r--r--actionpack/lib/action_controller/metal/url_for.rb10
-rw-r--r--actionpack/lib/action_controller/railtie.rb1
-rw-r--r--actionpack/lib/action_dispatch/middleware/session/abstract_store.rb5
-rw-r--r--actionpack/lib/action_dispatch/routing.rb12
-rw-r--r--actionpack/lib/action_dispatch/routing/deprecated_mapper.rb8
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb168
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb76
-rw-r--r--actionpack/lib/action_dispatch/routing/url_for.rb2
-rw-r--r--actionpack/lib/action_view/base.rb2
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb12
-rw-r--r--actionpack/lib/action_view/helpers/url_helper.rb2
-rw-r--r--actionpack/lib/action_view/test_case.rb10
-rw-r--r--actionpack/test/abstract/helper_test.rb2
-rw-r--r--actionpack/test/abstract_unit.rb25
-rw-r--r--actionpack/test/controller/helper_test.rb6
-rw-r--r--actionpack/test/controller/mime_responds_test.rb20
-rw-r--r--actionpack/test/controller/url_for_test.rb2
-rw-r--r--actionpack/test/dispatch/routing_test.rb277
-rw-r--r--actionpack/test/dispatch/session/cookie_store_test.rb22
-rw-r--r--actionpack/test/dispatch/url_generation_test.rb16
-rw-r--r--actionpack/test/template/url_helper_test.rb29
25 files changed, 533 insertions, 191 deletions
diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec
index b4311599a9..df0b5ac9a2 100644
--- a/actionpack/actionpack.gemspec
+++ b/actionpack/actionpack.gemspec
@@ -27,5 +27,5 @@ Gem::Specification.new do |s|
s.add_dependency('rack-test', '~> 0.5.4')
#s.add_dependency('rack-mount', '~> 0.6.6')
s.add_dependency('tzinfo', '~> 0.3.16')
- s.add_dependency('erubis', '~> 2.6.5')
+ s.add_dependency('erubis', '~> 2.6.6')
end
diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb
index 6e3998aa21..b81d5954eb 100644
--- a/actionpack/lib/abstract_controller/rendering.rb
+++ b/actionpack/lib/abstract_controller/rendering.rb
@@ -50,8 +50,8 @@ module AbstractController
if controller.respond_to?(:_helpers)
include controller._helpers
- if controller.respond_to?(:_router)
- include controller._router.url_helpers
+ if controller.respond_to?(:_routes)
+ include controller._routes.url_helpers
end
# TODO: Fix RJS to not require this
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index a70ba0d2e3..1a2cbaab65 100644
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -60,17 +60,11 @@ module ActionController
include ActionController::Compatibility
def self.inherited(klass)
- ::ActionController::Base.subclasses << klass.to_s
super
klass.helper :all
end
- def self.subclasses
- @subclasses ||= []
- end
-
config_accessor :asset_host, :asset_path
-
ActiveSupport.run_load_hooks(:action_controller, self)
end
end
diff --git a/actionpack/lib/action_controller/metal/helpers.rb b/actionpack/lib/action_controller/metal/helpers.rb
index 89201fb5ee..e0bc47318a 100644
--- a/actionpack/lib/action_controller/metal/helpers.rb
+++ b/actionpack/lib/action_controller/metal/helpers.rb
@@ -1,3 +1,4 @@
+require 'active_support/core_ext/array/wrap'
require 'active_support/core_ext/class/attribute'
module ActionController
@@ -64,7 +65,7 @@ module ActionController
def helpers_dir=(value)
ActiveSupport::Deprecation.warn "helpers_dir= is deprecated, use helpers_path= instead", caller
- self.helpers_path = Array(value)
+ self.helpers_path = Array.wrap(value)
end
# Declares helper accessors for controller attributes. For example, the
@@ -103,7 +104,7 @@ module ActionController
# Extract helper names from files in app/helpers/**/*_helper.rb
def all_application_helpers
helpers = []
- helpers_path.each do |path|
+ Array.wrap(helpers_path).each do |path|
extract = /^#{Regexp.quote(path.to_s)}\/?(.*)_helper.rb$/
helpers += Dir["#{path}/**/*_helper.rb"].map { |file| file.sub(extract, '\1') }
end
diff --git a/actionpack/lib/action_controller/metal/url_for.rb b/actionpack/lib/action_controller/metal/url_for.rb
index c465035ca1..a51fc5b8e4 100644
--- a/actionpack/lib/action_controller/metal/url_for.rb
+++ b/actionpack/lib/action_controller/metal/url_for.rb
@@ -12,17 +12,17 @@ module ActionController
).merge(:script_name => request.script_name)
end
- def _router
- raise "In order to use #url_for, you must include the helpers of a particular " \
- "router. For instance, `include Rails.application.routes.url_helpers"
+ def _routes
+ raise "In order to use #url_for, you must include routing helpers explicitly. " \
+ "For instance, `include Rails.application.routes.url_helpers"
end
module ClassMethods
def action_methods
@action_methods ||= begin
- super - _router.named_routes.helper_names
+ super - _routes.named_routes.helper_names
end
end
end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb
index 86395c4d93..9261422f0b 100644
--- a/actionpack/lib/action_controller/railtie.rb
+++ b/actionpack/lib/action_controller/railtie.rb
@@ -2,7 +2,6 @@ require "rails"
require "action_controller"
require "action_dispatch/railtie"
require "action_view/railtie"
-require "active_support/core_ext/class/subclasses"
require "active_support/deprecation/proxy_wrappers"
require "active_support/deprecation"
diff --git a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
index 08bc80dbc2..64f4d1d532 100644
--- a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
+++ b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
@@ -64,6 +64,11 @@ module ActionDispatch
super(key.to_s, value)
end
+ def clear
+ load_for_write!
+ super
+ end
+
def to_hash
load_for_read!
h = {}.replace(self)
diff --git a/actionpack/lib/action_dispatch/routing.rb b/actionpack/lib/action_dispatch/routing.rb
index 401d98b663..c664fb0bc2 100644
--- a/actionpack/lib/action_dispatch/routing.rb
+++ b/actionpack/lib/action_dispatch/routing.rb
@@ -31,7 +31,7 @@ module ActionDispatch
# Think of creating routes as drawing a map for your requests. The map tells
# them where to go based on some predefined pattern:
#
- # AppName::Applications.routes.draw do |map|
+ # AppName::Application.routes.draw do |map|
# Pattern 1 tells some request to go to one place
# Pattern 2 tell them to go to another
# ...
@@ -62,7 +62,7 @@ module ActionDispatch
#
# redirect_to show_item_path(:id => 25)
#
- # Use <tt>root</tt> as a shorthand to name a route for the root path "".
+ # Use <tt>root</tt> as a shorthand to name a route for the root path "/".
#
# # In routes.rb
# root :to => 'blogs#index'
@@ -72,7 +72,7 @@ module ActionDispatch
#
# # and provide these named routes
# root_url # => 'http://www.example.com/'
- # root_path # => ''
+ # root_path # => '/'
#
# Note: when using +controller+, the route is simply named after the
# method you call on the block parameter rather than map.
@@ -91,9 +91,7 @@ module ActionDispatch
#
# Routes can generate pretty URLs. For example:
#
- # match '/articles/:year/:month/:day', :constraints => {
- # :controller => 'articles',
- # :action => 'find_by_date',
+ # match '/articles/:year/:month/:day' => 'articles#find_by_id', :constraints => {
# :year => /\d{4}/,
# :month => /\d{1,2}/,
# :day => /\d{1,2}/
@@ -167,7 +165,7 @@ module ActionDispatch
#
# You can reload routes if you feel you must:
#
- # Rails::Application.reload_routes!
+ # Rails.application.reload_routes!
#
# This will clear all named routes and reload routes.rb if the file has been modified from
# last load. To absolutely force reloading, use <tt>reload!</tt>.
diff --git a/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb b/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb
index bc3f62fb48..b3146a1c60 100644
--- a/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb
@@ -19,9 +19,9 @@ module ActionDispatch
def in_memory_controller_namespaces
namespaces = Set.new
- ActionController::Base.subclasses.each do |klass|
- controller_name = klass.underscore
- namespaces << controller_name.split('/')[0...-1].join('/')
+ ActionController::Base.descendants.each do |klass|
+ next if klass.anonymous?
+ namespaces << klass.name.underscore.split('/')[0...-1].join('/')
end
namespaces.delete('')
namespaces
@@ -31,7 +31,7 @@ module ActionDispatch
class DeprecatedMapper #:nodoc:
def initialize(set) #:nodoc:
ActiveSupport::Deprecation.warn "You are using the old router DSL which will be removed in Rails 3.1. " <<
- "Please check how to update your router file at: http://www.engineyard.com/blog/2010/the-lowdown-on-routes-in-rails-3/"
+ "Please check how to update your routes file at: http://www.engineyard.com/blog/2010/the-lowdown-on-routes-in-rails-3/"
@set = set
end
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index 0b4ba8c9f5..430f6fc5a3 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -13,6 +13,8 @@ module ActionDispatch
end
end
+ attr_reader :app
+
def initialize(app, constraints, request)
@app, @constraints, @request = app, constraints, request
end
@@ -63,6 +65,16 @@ module ActionDispatch
end
end
+ if path.match(':controller')
+ raise ArgumentError, ":controller segment is not allowed within a namespace block" if @scope[:module]
+
+ # Add a default constraint for :controller path segments that matches namespaced
+ # controllers with default routes like :controller/:action/:id(.:format), e.g:
+ # GET /admin/products/show/1
+ # => { :controller => 'admin/products', :action => 'show', :id => '1' }
+ options.reverse_merge!(:controller => /.+?/)
+ end
+
path = normalize_path(path)
path_without_format = path.sub(/\(\.:format\)$/, '')
@@ -133,8 +145,11 @@ module ActionDispatch
defaults[:controller] ||= default_controller
defaults[:action] ||= default_action
- defaults.delete(:controller) if defaults[:controller].blank?
- defaults.delete(:action) if defaults[:action].blank?
+ defaults.delete(:controller) if defaults[:controller].blank? || defaults[:controller].is_a?(Regexp)
+ defaults.delete(:action) if defaults[:action].blank? || defaults[:action].is_a?(Regexp)
+
+ defaults[:controller] = defaults[:controller].to_s if defaults.key?(:controller)
+ defaults[:action] = defaults[:action].to_s if defaults.key?(:action)
if defaults[:controller].blank? && segment_keys.exclude?("controller")
raise ArgumentError, "missing :controller"
@@ -183,15 +198,15 @@ module ActionDispatch
def default_controller
if @options[:controller]
- @options[:controller].to_s
+ @options[:controller]
elsif @scope[:controller]
- @scope[:controller].to_s
+ @scope[:controller]
end
end
def default_action
if @options[:action]
- @options[:action].to_s
+ @options[:action]
end
end
end
@@ -431,12 +446,16 @@ module ActionDispatch
end
def merge_options_scope(parent, child)
- (parent || {}).merge(child)
+ (parent || {}).except(*override_keys(child)).merge(child)
end
def merge_shallow_scope(parent, child)
child ? true : false
end
+
+ def override_keys(child)
+ child.key?(:only) || child.key?(:except) ? [:only, :except] : []
+ end
end
module Resources
@@ -444,7 +463,7 @@ module ActionDispatch
# a path appended since they fit properly in their scope level.
VALID_ON_OPTIONS = [:new, :collection, :member]
CANONICAL_ACTIONS = [:index, :create, :new, :show, :update, :destroy]
- MERGE_FROM_SCOPE_OPTIONS = [:shallow, :constraints]
+ RESOURCE_OPTIONS = [:as, :controller, :path, :only, :except]
class Resource #:nodoc:
DEFAULT_ACTIONS = [:index, :create, :new, :show, :update, :destroy, :edit]
@@ -464,9 +483,9 @@ module ActionDispatch
end
def actions
- if only = options[:only]
+ if only = @options[:only]
Array(only).map(&:to_sym)
- elsif except = options[:except]
+ elsif except = @options[:except]
default_actions - Array(except).map(&:to_sym)
else
default_actions
@@ -489,68 +508,31 @@ module ActionDispatch
singular
end
- alias_method :nested_name, :member_name
-
# Checks for uncountable plurals, and appends "_index" if they're.
def collection_name
singular == plural ? "#{plural}_index" : plural
end
- def shallow?
- options[:shallow] ? true : false
- end
-
- def constraints
- options[:constraints] || {}
- end
-
- def id_constraint?
- options[:id] && options[:id].is_a?(Regexp) || constraints[:id] && constraints[:id].is_a?(Regexp)
- end
-
- def id_constraint
- options[:id] || constraints[:id]
- end
-
- def collection_options
- (options || {}).dup.tap do |opts|
- opts.delete(:id)
- opts[:constraints] = options[:constraints].dup if options[:constraints]
- opts[:constraints].delete(:id) if options[:constraints].is_a?(Hash)
- end
- end
-
- def nested_path
- "#{path}/:#{singular}_id"
- end
-
- def nested_options
- {}.tap do |opts|
- opts[:as] = member_name
- opts["#{singular}_id".to_sym] = id_constraint if id_constraint?
- opts[:options] = { :shallow => shallow? } unless options[:shallow].nil?
- end
- end
-
def resource_scope
- [{ :controller => controller }]
+ { :controller => controller }
end
def collection_scope
- [path, collection_options]
+ path
end
def member_scope
- ["#{path}/:id", options]
+ "#{path}/:id"
end
def new_scope(new_path)
- ["#{path}/#{new_path}"]
+ "#{path}/#{new_path}"
end
def nested_scope
- [nested_path, nested_options]
+ "#{path}/:#{singular}_id"
end
+
end
class SingletonResource < Resource #:nodoc:
@@ -559,7 +541,7 @@ module ActionDispatch
def initialize(entities, options)
@name = entities.to_s
@path = options.delete(:path) || @name
- @controller = (options.delete(:controller) || @name.to_s.pluralize).to_s
+ @controller = (options.delete(:controller) || plural).to_s
@as = options.delete(:as)
@options = options
end
@@ -569,24 +551,10 @@ module ActionDispatch
end
alias :collection_name :member_name
- def nested_path
- path
- end
-
- def nested_options
- {}.tap do |opts|
- opts[:as] = member_name
- opts[:options] = { :shallow => shallow? } unless @options[:shallow].nil?
- end
- end
-
- def shallow?
- false
- end
-
def member_scope
- [path, options]
+ path
end
+ alias :nested_scope :member_scope
end
def initialize(*args) #:nodoc:
@@ -693,18 +661,18 @@ module ActionDispatch
end
with_scope_level(:nested) do
- if parent_resource.shallow?
+ if shallow?
with_exclusive_scope do
if @scope[:shallow_path].blank?
- scope(*parent_resource.nested_scope) { yield }
+ scope(parent_resource.nested_scope, nested_options) { yield }
else
scope(@scope[:shallow_path], :as => @scope[:shallow_prefix]) do
- scope(*parent_resource.nested_scope) { yield }
+ scope(parent_resource.nested_scope, nested_options) { yield }
end
end
end
else
- scope(*parent_resource.nested_scope) { yield }
+ scope(parent_resource.nested_scope, nested_options) { yield }
end
end
end
@@ -723,6 +691,10 @@ module ActionDispatch
end
end
+ def shallow?
+ parent_resource.instance_of?(Resource) && @scope[:shallow]
+ end
+
def match(*args)
options = args.extract_options!.dup
options[:anchor] = true unless options.key?(:anchor)
@@ -800,16 +772,17 @@ module ActionDispatch
return true
end
- if path_names = options.delete(:path_names)
- scope(:path_names => path_names) do
+ scope_options = options.slice!(*RESOURCE_OPTIONS)
+ unless scope_options.empty?
+ scope(scope_options) do
send(method, resources.pop, options, &block)
end
return true
end
- scope_options = @scope.slice(*MERGE_FROM_SCOPE_OPTIONS).delete_if{ |k,v| v.blank? }
- options.reverse_merge!(scope_options) unless scope_options.empty?
- options.reverse_merge!(@scope[:options]) unless @scope[:options].blank?
+ unless action_options?(options)
+ options.merge!(scope_action_options) if scope_action_options?
+ end
if resource_scope?
nested do
@@ -821,6 +794,18 @@ module ActionDispatch
false
end
+ def action_options?(options)
+ options[:only] || options[:except]
+ end
+
+ def scope_action_options?
+ @scope[:options].is_a?(Hash) && (@scope[:options][:only] || @scope[:options][:except])
+ end
+
+ def scope_action_options
+ @scope[:options].slice(:only, :except)
+ end
+
def resource_scope?
[:resource, :resources].include?(@scope[:scope_level])
end
@@ -853,7 +838,7 @@ module ActionDispatch
def resource_scope(resource)
with_scope_level(resource.is_a?(SingletonResource) ? :resource : :resources, resource) do
- scope(*parent_resource.resource_scope) do
+ scope(parent_resource.resource_scope) do
yield
end
end
@@ -861,7 +846,7 @@ module ActionDispatch
def new_scope
with_scope_level(:new) do
- scope(*parent_resource.new_scope(action_path(:new))) do
+ scope(parent_resource.new_scope(action_path(:new))) do
yield
end
end
@@ -869,7 +854,7 @@ module ActionDispatch
def collection_scope
with_scope_level(:collection) do
- scope(*parent_resource.collection_scope) do
+ scope(parent_resource.collection_scope) do
yield
end
end
@@ -877,18 +862,33 @@ module ActionDispatch
def member_scope
with_scope_level(:member) do
- scope(*parent_resource.member_scope) do
+ scope(parent_resource.member_scope) do
yield
end
end
end
+ def nested_options
+ {}.tap do |options|
+ options[:as] = parent_resource.member_name
+ options[:constraints] = { "#{parent_resource.singular}_id".to_sym => id_constraint } if id_constraint?
+ end
+ end
+
+ def id_constraint?
+ @scope[:id].is_a?(Regexp) || (@scope[:constraints] && @scope[:constraints][:id].is_a?(Regexp))
+ end
+
+ def id_constraint
+ @scope[:id] || @scope[:constraints][:id]
+ end
+
def canonical_action?(action, flag)
flag && CANONICAL_ACTIONS.include?(action)
end
def shallow_scoping?
- parent_resource && parent_resource.shallow? && @scope[:scope_level] == :member
+ shallow? && @scope[:scope_level] == :member
end
def path_for_action(action, path)
@@ -932,7 +932,7 @@ module ActionDispatch
collection_name = parent_resource.collection_name
member_name = parent_resource.member_name
name_prefix = "#{name_prefix}_" if name_prefix.present?
- end
+ end
case @scope[:scope_level]
when :collection
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index 5ecad6bc04..1b1a221c60 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -26,7 +26,7 @@ module ActionDispatch
return [404, {'X-Cascade' => 'pass'}, []]
end
- controller.action(params[:action]).call(env)
+ dispatch(controller, params[:action], env)
end
def prepare_params!(params)
@@ -34,29 +34,43 @@ module ActionDispatch
split_glob_param!(params) if @glob_param
end
- def controller(params, raise_error=true)
+ # If this is a default_controller (i.e. a controller specified by the user)
+ # we should raise an error in case it's not found, because it usually means
+ # an user error. However, if the controller was retrieved through a dynamic
+ # segment, as in :controller(/:action), we should simply return nil and
+ # delegate the control back to Rack cascade. Besides, if this is not a default
+ # controller, it means we should respect the @scope[:module] parameter.
+ def controller(params, default_controller=true)
if params && params.key?(:controller)
controller_param = params[:controller]
- unless controller = @controllers[controller_param]
- controller_name = "#{controller_param.camelize}Controller"
- controller = @controllers[controller_param] =
- ActiveSupport::Dependencies.ref(controller_name)
- end
-
- controller.get
+ controller_reference(controller_param)
end
rescue NameError => e
- raise ActionController::RoutingError, e.message, e.backtrace if raise_error
+ raise ActionController::RoutingError, e.message, e.backtrace if default_controller
end
- private
- def merge_default_action!(params)
- params[:action] ||= 'index'
- end
+ private
- def split_glob_param!(params)
- params[@glob_param] = params[@glob_param].split('/').map { |v| URI.unescape(v) }
+ def controller_reference(controller_param)
+ unless controller = @controllers[controller_param]
+ controller_name = "#{controller_param.camelize}Controller"
+ controller = @controllers[controller_param] =
+ ActiveSupport::Dependencies.ref(controller_name)
end
+ controller.get
+ end
+
+ def dispatch(controller, action, env)
+ controller.action(action).call(env)
+ end
+
+ def merge_default_action!(params)
+ params[:action] ||= 'index'
+ end
+
+ def split_glob_param!(params)
+ params[@glob_param] = params[@glob_param].split('/').map { |v| URI.unescape(v) }
+ end
end
# A NamedRouteCollection instance is a collection of named routes, and also
@@ -268,10 +282,10 @@ module ActionDispatch
# Yes plz - JP
included do
routes.install_helpers(self)
- singleton_class.send(:define_method, :_router) { routes }
+ singleton_class.send(:define_method, :_routes) { routes }
end
- define_method(:_router) { routes }
+ define_method(:_routes) { routes }
end
helpers
@@ -302,7 +316,6 @@ module ActionDispatch
@extras = extras
normalize_options!
- normalize_recall!
normalize_controller_action_id!
use_relative_controller!
controller.sub!(%r{^/}, '') if controller
@@ -319,7 +332,11 @@ module ActionDispatch
def use_recall_for(key)
if @recall[key] && (!@options.key?(key) || @options[key] == @recall[key])
- @options[key] = @recall.delete(key)
+ if named_route_exists?
+ @options[key] = @recall.delete(key) if segment_keys.include?(key)
+ else
+ @options[key] = @recall.delete(key)
+ end
end
end
@@ -343,15 +360,6 @@ module ActionDispatch
end
end
- def normalize_recall!
- # If the target route is not a standard route then remove controller and action
- # from the options otherwise they will appear in the url parameters
- if block_or_proc_route_target?
- recall.delete(:controller) unless segment_keys.include?(:controller)
- recall.delete(:action) unless segment_keys.include?(:action)
- end
- end
-
# This pulls :controller, :action, and :id out of the recall.
# The recall key is only used if there is no key in the options
# or if the key in the options is identical. If any of
@@ -424,12 +432,8 @@ module ActionDispatch
named_route && set.named_routes[named_route]
end
- def block_or_proc_route_target?
- named_route_exists? && !set.named_routes[named_route].app.is_a?(Dispatcher)
- end
-
def segment_keys
- named_route_exists? ? set.named_routes[named_route].segment_keys : []
+ set.named_routes[named_route].segment_keys
end
end
@@ -474,7 +478,7 @@ module ActionDispatch
path_options = yield(path_options) if block_given?
path = generate(path_options, path_segments || {})
- # ROUTES TODO: This can be called directly, so script_name should probably be set in the router
+ # ROUTES TODO: This can be called directly, so script_name should probably be set in the routes
rewritten_url << (options[:trailing_slash] ? path.sub(/\?|\z/) { "/" + $& } : path)
rewritten_url << "##{Rack::Mount::Utils.escape_uri(options[:anchor].to_param.to_s)}" if options[:anchor]
@@ -506,6 +510,8 @@ module ActionDispatch
end
dispatcher = route.app
+ dispatcher = dispatcher.app while dispatcher.is_a?(Mapper::Constraints)
+
if dispatcher.is_a?(Dispatcher) && dispatcher.controller(params, false)
dispatcher.prepare_params!(params)
return params
diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb
index db17615d92..980abd44df 100644
--- a/actionpack/lib/action_dispatch/routing/url_for.rb
+++ b/actionpack/lib/action_dispatch/routing/url_for.rb
@@ -128,7 +128,7 @@ module ActionDispatch
when String
options
when nil, Hash
- _router.url_for(url_options.merge((options || {}).symbolize_keys))
+ _routes.url_for(url_options.merge((options || {}).symbolize_keys))
else
polymorphic_url(options)
end
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index 956c88a553..20a2e7c1f0 100644
--- a/actionpack/lib/action_view/base.rb
+++ b/actionpack/lib/action_view/base.rb
@@ -173,7 +173,7 @@ module ActionView #:nodoc:
@@field_error_proc = Proc.new{ |html_tag, instance| "<div class=\"field_with_errors\">#{html_tag}</div>".html_safe }
class_attribute :helpers
- class_attribute :_router
+ class_attribute :_routes
class << self
delegate :erb_trim_mode=, :to => 'ActionView::Template::Handlers::ERB'
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index d1b10a9281..6302491c2a 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -213,12 +213,22 @@ module ActionView
# ...
# <% end %>
#
- # And for namespaced routes, like +admin_post_url+:
+ # For namespaced routes, like +admin_post_url+:
#
# <%= form_for([:admin, @post]) do |f| %>
# ...
# <% end %>
#
+ # If your resource has associations defined, for example, you want to add comments
+ # to the post given that the routes are set correctly:
+ #
+ # <%= form_for([@document, @comment]) do |f| %>
+ # ...
+ # <% end %>
+ #
+ # Where +@document = Document.find(params[:id])+ and
+ # +@comment = Comment.new+.
+ #
# === Unobtrusive JavaScript
#
# Specifying:
diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb
index b8d6dc22f2..0e3cc54fd1 100644
--- a/actionpack/lib/action_view/helpers/url_helper.rb
+++ b/actionpack/lib/action_view/helpers/url_helper.rb
@@ -12,7 +12,7 @@ module ActionView
# and controllers.
module UrlHelper
# This helper may be included in any class that includes the
- # URL helpers of a router (router.url_helpers). Some methods
+ # URL helpers of a routes (routes.url_helpers). Some methods
# provided here will only work in the4 context of a request
# (link_to_unless_current, for instance), which must be provided
# as a method called #request on the context.
diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb
index e5614c9e3b..56aebca957 100644
--- a/actionpack/lib/action_view/test_case.rb
+++ b/actionpack/lib/action_view/test_case.rb
@@ -151,7 +151,7 @@ module ActionView
@view ||= begin
view = ActionView::Base.new(ActionController::Base.view_paths, {}, @controller)
view.singleton_class.send :include, _helpers
- view.singleton_class.send :include, @controller._router.url_helpers
+ view.singleton_class.send :include, @controller._routes.url_helpers
view.singleton_class.send :delegate, :alert, :notice, :to => "request.flash"
view.extend(Locals)
view.locals = self.locals
@@ -192,13 +192,13 @@ module ActionView
end
end
- def _router
- @controller._router if @controller.respond_to?(:_router)
+ def _routes
+ @controller._routes if @controller.respond_to?(:_routes)
end
def method_missing(selector, *args)
- if @controller.respond_to?(:_router) &&
- @controller._router.named_routes.helpers.include?(selector)
+ if @controller.respond_to?(:_routes) &&
+ @controller._routes.named_routes.helpers.include?(selector)
@controller.__send__(selector, *args)
else
super
diff --git a/actionpack/test/abstract/helper_test.rb b/actionpack/test/abstract/helper_test.rb
index 0cdf5c2298..15c27501f2 100644
--- a/actionpack/test/abstract/helper_test.rb
+++ b/actionpack/test/abstract/helper_test.rb
@@ -1,6 +1,6 @@
require 'abstract_unit'
-ActionController::Base.helpers_path = [File.dirname(__FILE__) + '/../fixtures/helpers']
+ActionController::Base.helpers_path = File.expand_path('../../fixtures/helpers', __FILE__)
module AbstractController
module Testing
diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb
index c8477fb83f..5be47f7c96 100644
--- a/actionpack/test/abstract_unit.rb
+++ b/actionpack/test/abstract_unit.rb
@@ -41,7 +41,7 @@ require 'pp' # require 'pp' early to prevent hidden_methods from not picking up
module Rails
end
-# Monkey patch the old router initialization to be silenced.
+# Monkey patch the old routes initialization to be silenced.
class ActionDispatch::Routing::DeprecatedMapper
def initialize_with_silencer(*args)
ActiveSupport::Deprecation.silence { initialize_without_silencer(*args) }
@@ -182,13 +182,16 @@ class ActionController::IntegrationTest < ActiveSupport::TestCase
self.app = build_app
- class StubDispatcher
- def self.new(*args)
- lambda { |env|
- params = env['action_dispatch.request.path_parameters']
- controller, action = params[:controller], params[:action]
- [200, {'Content-Type' => 'text/html'}, ["#{controller}##{action}"]]
- }
+ # Stub Rails dispatcher so it does not get controller references and
+ # simply return the controller#action as Rack::Body.
+ class StubDispatcher < ::ActionDispatch::Routing::RouteSet::Dispatcher
+ protected
+ def controller_reference(controller_param)
+ controller_param
+ end
+
+ def dispatch(controller, action, env)
+ [200, {'Content-Type' => 'text/html'}, ["#{controller}##{action}"]]
end
end
@@ -275,9 +278,9 @@ end
class ActionController::Base
def self.test_routes(&block)
- router = ActionDispatch::Routing::RouteSet.new
- router.draw(&block)
- include router.url_helpers
+ routes = ActionDispatch::Routing::RouteSet.new
+ routes.draw(&block)
+ include routes.url_helpers
end
end
diff --git a/actionpack/test/controller/helper_test.rb b/actionpack/test/controller/helper_test.rb
index c9a6e5dd45..9b9657929f 100644
--- a/actionpack/test/controller/helper_test.rb
+++ b/actionpack/test/controller/helper_test.rb
@@ -1,7 +1,7 @@
require 'abstract_unit'
require 'active_support/core_ext/kernel/reporting'
-ActionController::Base.helpers_path = [File.dirname(__FILE__) + '/../fixtures/helpers']
+ActionController::Base.helpers_path = File.expand_path('../../fixtures/helpers', __FILE__)
module Fun
class GamesController < ActionController::Base
@@ -106,7 +106,7 @@ class HelperTest < ActiveSupport::TestCase
end
def test_all_helpers_with_alternate_helper_dir
- @controller_class.helpers_path = [File.dirname(__FILE__) + '/../fixtures/alternate_helpers']
+ @controller_class.helpers_path = File.expand_path('../../fixtures/alternate_helpers', __FILE__)
# Reload helpers
@controller_class._helpers = Module.new
@@ -143,7 +143,7 @@ class HelperTest < ActiveSupport::TestCase
assert_equal ["some/foo/bar"], ActionController::Base.helpers_dir
end
ensure
- ActionController::Base.helpers_path = [File.dirname(__FILE__) + '/../fixtures/helpers']
+ ActionController::Base.helpers_path = File.expand_path('../../fixtures/helpers', __FILE__)
end
private
diff --git a/actionpack/test/controller/mime_responds_test.rb b/actionpack/test/controller/mime_responds_test.rb
index d654338dba..b5ce391b61 100644
--- a/actionpack/test/controller/mime_responds_test.rb
+++ b/actionpack/test/controller/mime_responds_test.rb
@@ -36,6 +36,15 @@ class RespondToController < ActionController::Base
type.all { render :text => "Nothing" }
end
end
+
+ def json_xml_or_html
+ respond_to do |type|
+ type.json { render :text => 'JSON' }
+ type.xml { render :xml => 'XML' }
+ type.html { render :text => 'HTML' }
+ end
+ end
+
def forced_xml
request.format = :xml
@@ -364,6 +373,17 @@ class RespondToControllerTest < ActionController::TestCase
get :handle_any_any
assert_equal 'Whatever you ask for, I got it', @response.body
end
+
+ def test_browser_check_with_any_any
+ @request.accept = "application/json, application/xml"
+ get :json_xml_or_html
+ assert_equal 'JSON', @response.body
+
+ @request.accept = "application/json, application/xml, */*"
+ get :json_xml_or_html
+ assert_equal 'HTML', @response.body
+ end
+
def test_rjs_type_skips_layout
@request.accept = "text/javascript"
diff --git a/actionpack/test/controller/url_for_test.rb b/actionpack/test/controller/url_for_test.rb
index 4b30b0af36..71a4a43477 100644
--- a/actionpack/test/controller/url_for_test.rb
+++ b/actionpack/test/controller/url_for_test.rb
@@ -120,7 +120,7 @@ module AbstractController
def test_relative_url_root_is_respected
# ROUTES TODO: Tests should not have to pass :relative_url_root directly. This
- # should probably come from the router.
+ # should probably come from routes.
add_host!
assert_equal('https://www.basecamphq.com/subdir/c/a/i',
diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb
index 26bd641cd6..2a014bf976 100644
--- a/actionpack/test/dispatch/routing_test.rb
+++ b/actionpack/test/dispatch/routing_test.rb
@@ -45,7 +45,10 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
match 'account/logout' => redirect("/logout"), :as => :logout_redirect
match 'account/login', :to => redirect("/login")
- match 'account/overview'
+ constraints(lambda { |req| true }) do
+ match 'account/overview'
+ end
+
match '/account/nested/overview'
match 'sign_in' => "sessions#new"
@@ -298,8 +301,8 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
resource :dashboard, :constraints => { :ip => /192\.168\.1\.\d{1,3}/ }
+ resource :token, :module => :api
scope :module => :api do
- resource :token
resources :errors, :shallow => true do
resources :notices
end
@@ -310,11 +313,6 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
match '/' => 'mes#index'
end
- namespace :private do
- root :to => redirect('/private/index')
- match "index", :to => 'private#index'
- end
-
get "(/:username)/followers" => "followers#index"
get "/groups(/user/:username)" => "groups#index"
get "(/user/:username)/photos" => "photos#index"
@@ -325,7 +323,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
- match "whatever/:controller(/:action(/:id))"
+ match "whatever/:controller(/:action(/:id))", :id => /\d+/
resource :profile do
get :settings
@@ -348,6 +346,63 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
+ namespace :private do
+ root :to => redirect('/private/index')
+ match "index", :to => 'private#index'
+ end
+
+ scope :only => [:index, :show] do
+ namespace :only do
+ resources :clubs do
+ resources :players
+ resource :chairman
+ end
+ end
+ end
+
+ scope :except => [:new, :create, :edit, :update, :destroy] do
+ namespace :except do
+ resources :clubs do
+ resources :players
+ resource :chairman
+ end
+ end
+ end
+
+ scope :only => :show do
+ namespace :only do
+ resources :sectors, :only => :index do
+ resources :companies do
+ scope :only => :index do
+ resources :divisions
+ end
+ scope :except => [:show, :update, :destroy] do
+ resources :departments
+ end
+ end
+ resource :leader
+ resources :managers, :except => [:show, :update, :destroy]
+ end
+ end
+ end
+
+ scope :except => :index do
+ namespace :except do
+ resources :sectors, :except => [:show, :update, :destroy] do
+ resources :companies do
+ scope :except => [:show, :update, :destroy] do
+ resources :divisions
+ end
+ scope :only => :index do
+ resources :departments
+ end
+ end
+ resource :leader
+ resources :managers, :only => :index
+ end
+ end
+ end
+
match '/:locale/*file.:format', :to => 'files#show', :file => /path\/to\/existing\/file/
end
end
@@ -470,6 +525,18 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
+ def test_namespace_with_controller_segment
+ assert_raise(ArgumentError) do
+ self.class.stub_controllers do |routes|
+ routes.draw do
+ namespace :admin do
+ match '/:controller(/:action(/:id(.:format)))'
+ end
+ end
+ end
+ end
+ end
+
def test_session_singleton_resource
with_test_routes do
get '/session'
@@ -1240,7 +1307,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
assert_equal 'pass', @response.headers['X-Cascade']
get '/products/0001/images'
assert_equal 'images#index', @response.body
- get '/products/0001/images/1'
+ get '/products/0001/images/0001'
assert_equal 'images#show', @response.body
get '/dashboard', {}, {'REMOTE_ADDR' => '10.0.0.100'}
@@ -1285,6 +1352,22 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
+ def test_url_generator_for_namespaced_generic_route
+ with_test_routes do
+ get 'whatever/foo/bar/show'
+ assert_equal 'foo/bar#show', @response.body
+
+ get 'whatever/foo/bar/show/1'
+ assert_equal 'foo/bar#show', @response.body
+
+ assert_equal 'http://www.example.com/whatever/foo/bar/show',
+ url_for(:controller => "foo/bar", :action => "show")
+
+ assert_equal 'http://www.example.com/whatever/foo/bar/show/1',
+ url_for(:controller => "foo/bar", :action => "show", :id => '1')
+ end
+ end
+
def test_assert_recognizes_account_overview
with_test_routes do
assert_recognizes({:controller => "account", :action => "overview"}, "/account/overview")
@@ -1628,6 +1711,182 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
end
end
+ def test_only_should_be_read_from_scope
+ with_test_routes do
+ get '/only/clubs'
+ assert_equal 'only/clubs#index', @response.body
+ assert_equal '/only/clubs', only_clubs_path
+
+ get '/only/clubs/1/edit'
+ assert_equal 'Not Found', @response.body
+ assert_raise(NoMethodError) { edit_only_club_path(:id => '1') }
+
+ get '/only/clubs/1/players'
+ assert_equal 'only/players#index', @response.body
+ assert_equal '/only/clubs/1/players', only_club_players_path(:club_id => '1')
+
+ get '/only/clubs/1/players/2/edit'
+ assert_equal 'Not Found', @response.body
+ assert_raise(NoMethodError) { edit_only_club_player_path(:club_id => '1', :id => '2') }
+
+ get '/only/clubs/1/chairman'
+ assert_equal 'only/chairmen#show', @response.body
+ assert_equal '/only/clubs/1/chairman', only_club_chairman_path(:club_id => '1')
+
+ get '/only/clubs/1/chairman/edit'
+ assert_equal 'Not Found', @response.body
+ assert_raise(NoMethodError) { edit_only_club_chairman_path(:club_id => '1') }
+ end
+ end
+
+ def test_except_should_be_read_from_scope
+ with_test_routes do
+ get '/except/clubs'
+ assert_equal 'except/clubs#index', @response.body
+ assert_equal '/except/clubs', except_clubs_path
+
+ get '/except/clubs/1/edit'
+ assert_equal 'Not Found', @response.body
+ assert_raise(NoMethodError) { edit_except_club_path(:id => '1') }
+
+ get '/except/clubs/1/players'
+ assert_equal 'except/players#index', @response.body
+ assert_equal '/except/clubs/1/players', except_club_players_path(:club_id => '1')
+
+ get '/except/clubs/1/players/2/edit'
+ assert_equal 'Not Found', @response.body
+ assert_raise(NoMethodError) { edit_except_club_player_path(:club_id => '1', :id => '2') }
+
+ get '/except/clubs/1/chairman'
+ assert_equal 'except/chairmen#show', @response.body
+ assert_equal '/except/clubs/1/chairman', except_club_chairman_path(:club_id => '1')
+
+ get '/except/clubs/1/chairman/edit'
+ assert_equal 'Not Found', @response.body
+ assert_raise(NoMethodError) { edit_except_club_chairman_path(:club_id => '1') }
+ end
+ end
+
+ def test_only_option_should_override_scope
+ with_test_routes do
+ get '/only/sectors'
+ assert_equal 'only/sectors#index', @response.body
+ assert_equal '/only/sectors', only_sectors_path
+
+ get '/only/sectors/1'
+ assert_equal 'Not Found', @response.body
+ assert_raise(NoMethodError) { only_sector_path(:id => '1') }
+ end
+ end
+
+ def test_only_option_should_not_inherit
+ with_test_routes do
+ get '/only/sectors/1/companies/2'
+ assert_equal 'only/companies#show', @response.body
+ assert_equal '/only/sectors/1/companies/2', only_sector_company_path(:sector_id => '1', :id => '2')
+
+ get '/only/sectors/1/leader'
+ assert_equal 'only/leaders#show', @response.body
+ assert_equal '/only/sectors/1/leader', only_sector_leader_path(:sector_id => '1')
+ end
+ end
+
+ def test_except_option_should_override_scope
+ with_test_routes do
+ get '/except/sectors'
+ assert_equal 'except/sectors#index', @response.body
+ assert_equal '/except/sectors', except_sectors_path
+
+ get '/except/sectors/1'
+ assert_equal 'Not Found', @response.body
+ assert_raise(NoMethodError) { except_sector_path(:id => '1') }
+ end
+ end
+
+ def test_except_option_should_not_inherit
+ with_test_routes do
+ get '/except/sectors/1/companies/2'
+ assert_equal 'except/companies#show', @response.body
+ assert_equal '/except/sectors/1/companies/2', except_sector_company_path(:sector_id => '1', :id => '2')
+
+ get '/except/sectors/1/leader'
+ assert_equal 'except/leaders#show', @response.body
+ assert_equal '/except/sectors/1/leader', except_sector_leader_path(:sector_id => '1')
+ end
+ end
+
+ def test_except_option_should_override_scoped_only
+ with_test_routes do
+ get '/only/sectors/1/managers'
+ assert_equal 'only/managers#index', @response.body
+ assert_equal '/only/sectors/1/managers', only_sector_managers_path(:sector_id => '1')
+
+ get '/only/sectors/1/managers/2'
+ assert_equal 'Not Found', @response.body
+ assert_raise(NoMethodError) { only_sector_manager_path(:sector_id => '1', :id => '2') }
+ end
+ end
+
+ def test_only_option_should_override_scoped_except
+ with_test_routes do
+ get '/except/sectors/1/managers'
+ assert_equal 'except/managers#index', @response.body
+ assert_equal '/except/sectors/1/managers', except_sector_managers_path(:sector_id => '1')
+
+ get '/except/sectors/1/managers/2'
+ assert_equal 'Not Found', @response.body
+ assert_raise(NoMethodError) { except_sector_manager_path(:sector_id => '1', :id => '2') }
+ end
+ end
+
+ def test_only_scope_should_override_parent_scope
+ with_test_routes do
+ get '/only/sectors/1/companies/2/divisions'
+ assert_equal 'only/divisions#index', @response.body
+ assert_equal '/only/sectors/1/companies/2/divisions', only_sector_company_divisions_path(:sector_id => '1', :company_id => '2')
+
+ get '/only/sectors/1/companies/2/divisions/3'
+ assert_equal 'Not Found', @response.body
+ assert_raise(NoMethodError) { only_sector_company_division_path(:sector_id => '1', :company_id => '2', :id => '3') }
+ end
+ end
+
+ def test_except_scope_should_override_parent_scope
+ with_test_routes do
+ get '/except/sectors/1/companies/2/divisions'
+ assert_equal 'except/divisions#index', @response.body
+ assert_equal '/except/sectors/1/companies/2/divisions', except_sector_company_divisions_path(:sector_id => '1', :company_id => '2')
+
+ get '/except/sectors/1/companies/2/divisions/3'
+ assert_equal 'Not Found', @response.body
+ assert_raise(NoMethodError) { except_sector_company_division_path(:sector_id => '1', :company_id => '2', :id => '3') }
+ end
+ end
+
+ def test_except_scope_should_override_parent_only_scope
+ with_test_routes do
+ get '/only/sectors/1/companies/2/departments'
+ assert_equal 'only/departments#index', @response.body
+ assert_equal '/only/sectors/1/companies/2/departments', only_sector_company_departments_path(:sector_id => '1', :company_id => '2')
+
+ get '/only/sectors/1/companies/2/departments/3'
+ assert_equal 'Not Found', @response.body
+ assert_raise(NoMethodError) { only_sector_company_department_path(:sector_id => '1', :company_id => '2', :id => '3') }
+ end
+ end
+
+ def test_only_scope_should_override_parent_except_scope
+ with_test_routes do
+ get '/except/sectors/1/companies/2/departments'
+ assert_equal 'except/departments#index', @response.body
+ assert_equal '/except/sectors/1/companies/2/departments', except_sector_company_departments_path(:sector_id => '1', :company_id => '2')
+
+ get '/except/sectors/1/companies/2/departments/3'
+ assert_equal 'Not Found', @response.body
+ assert_raise(NoMethodError) { except_sector_company_department_path(:sector_id => '1', :company_id => '2', :id => '3') }
+ end
+ end
+
private
def with_test_routes
yield
diff --git a/actionpack/test/dispatch/session/cookie_store_test.rb b/actionpack/test/dispatch/session/cookie_store_test.rb
index fd63f5ad5e..f0e01bfff0 100644
--- a/actionpack/test/dispatch/session/cookie_store_test.rb
+++ b/actionpack/test/dispatch/session/cookie_store_test.rb
@@ -30,6 +30,11 @@ class CookieStoreTest < ActionController::IntegrationTest
render :text => "id: #{request.session_options[:id]}"
end
+ def call_session_clear
+ session.clear
+ head :ok
+ end
+
def call_reset_session
reset_session
head :ok
@@ -175,6 +180,23 @@ class CookieStoreTest < ActionController::IntegrationTest
end
end
+ def test_setting_session_value_after_session_clear
+ with_test_route_set do
+ get '/set_session_value'
+ assert_response :success
+ session_payload = response.body
+ assert_equal "_myapp_session=#{response.body}; path=/; HttpOnly",
+ headers['Set-Cookie']
+
+ get '/call_session_clear'
+ assert_response :success
+
+ get '/get_session_value'
+ assert_response :success
+ assert_equal 'foo: nil', response.body
+ end
+ end
+
def test_persistent_session_id
with_test_route_set do
cookies[SessionKey] = SignedBar
diff --git a/actionpack/test/dispatch/url_generation_test.rb b/actionpack/test/dispatch/url_generation_test.rb
index 326b336a1a..f83651d583 100644
--- a/actionpack/test/dispatch/url_generation_test.rb
+++ b/actionpack/test/dispatch/url_generation_test.rb
@@ -2,24 +2,24 @@ require 'abstract_unit'
module TestUrlGeneration
class WithMountPoint < ActionDispatch::IntegrationTest
- Router = ActionDispatch::Routing::RouteSet.new
- Router.draw { match "/foo", :to => "my_route_generating#index", :as => :foo }
+ Routes = ActionDispatch::Routing::RouteSet.new
+ Routes.draw { match "/foo", :to => "my_route_generating#index", :as => :foo }
class ::MyRouteGeneratingController < ActionController::Base
- include Router.url_helpers
+ include Routes.url_helpers
def index
render :text => foo_path
end
end
- include Router.url_helpers
+ include Routes.url_helpers
- def _router
- Router
+ def _routes
+ Routes
end
def app
- Router
+ Routes
end
test "generating URLS normally" do
@@ -30,7 +30,7 @@ module TestUrlGeneration
assert_equal "/bar/foo", foo_path(:script_name => "/bar")
end
- test "the request's SCRIPT_NAME takes precedence over the router's" do
+ test "the request's SCRIPT_NAME takes precedence over the routes'" do
get "/foo", {}, 'SCRIPT_NAME' => "/new"
assert_equal "/new/foo", response.body
end
diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb
index 765beebfa3..048f96c9a9 100644
--- a/actionpack/test/template/url_helper_test.rb
+++ b/actionpack/test/template/url_helper_test.rb
@@ -406,6 +406,14 @@ end
class UrlHelperControllerTest < ActionController::TestCase
class UrlHelperController < ActionController::Base
test_routes do |map|
+ match 'url_helper_controller_test/url_helper/show/:id',
+ :to => 'url_helper_controller_test/url_helper#show',
+ :as => :show
+
+ match 'url_helper_controller_test/url_helper/profile/:name',
+ :to => 'url_helper_controller_test/url_helper#show',
+ :as => :profile
+
match 'url_helper_controller_test/url_helper/show_named_route',
:to => 'url_helper_controller_test/url_helper#show_named_route',
:as => :show_named_route
@@ -418,6 +426,14 @@ class UrlHelperControllerTest < ActionController::TestCase
:as => :normalize_recall_params
end
+ def show
+ if params[:name]
+ render :inline => 'ok'
+ else
+ redirect_to profile_path(params[:id])
+ end
+ end
+
def show_url_for
render :inline => "<%= url_for :controller => 'url_helper_controller_test/url_helper', :action => 'show_url_for' %>"
end
@@ -484,15 +500,24 @@ class UrlHelperControllerTest < ActionController::TestCase
assert_equal 'http://testtwo.host/url_helper_controller_test/url_helper/show_named_route', @response.body
end
- def test_recall_params_should_be_normalized_when_using_block_route
+ def test_recall_params_should_be_normalized
get :normalize_recall_params
assert_equal '/url_helper_controller_test/url_helper/normalize_recall_params', @response.body
end
- def test_recall_params_should_not_be_changed_when_using_normal_route
+ def test_recall_params_should_not_be_changed
get :recall_params_not_changed
assert_equal '/url_helper_controller_test/url_helper/show_url_for', @response.body
end
+
+ def test_recall_params_should_normalize_id
+ get :show, :id => '123'
+ assert_equal 302, @response.status
+ assert_equal 'http://test.host/url_helper_controller_test/url_helper/profile/123', @response.location
+
+ get :show, :name => '123'
+ assert_equal 'ok', @response.body
+ end
end
class TasksController < ActionController::Base