diff options
author | José Valim <jose.valim@gmail.com> | 2009-12-02 22:29:34 -0200 |
---|---|---|
committer | José Valim <jose.valim@gmail.com> | 2009-12-02 22:29:34 -0200 |
commit | 6e55b32e98fcaad82184d2e21ee611a3465e4b20 (patch) | |
tree | e316b8ca72f2bef50668c222400a159b36fbc090 /actionpack | |
parent | c2e97cb410d759f383d29920165abdbf4b70e019 (diff) | |
parent | 399909b11c094ab32542d300c72940b1b263b8e6 (diff) | |
download | rails-6e55b32e98fcaad82184d2e21ee611a3465e4b20.tar.gz rails-6e55b32e98fcaad82184d2e21ee611a3465e4b20.tar.bz2 rails-6e55b32e98fcaad82184d2e21ee611a3465e4b20.zip |
Merge branch 'master' of git://github.com/rails/rails
Diffstat (limited to 'actionpack')
-rw-r--r-- | actionpack/actionpack.gemspec | 2 | ||||
-rw-r--r-- | actionpack/lib/action_controller/metal/compatibility.rb | 5 | ||||
-rw-r--r-- | actionpack/lib/action_controller/metal/responder.rb | 11 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/http/response.rb | 9 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/routing.rb | 68 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/routing/deprecated_mapper.rb | 4 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/routing/mapper.rb | 2 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/routing/route_set.rb | 63 | ||||
-rw-r--r-- | actionpack/lib/action_view/render/partials.rb | 20 | ||||
-rw-r--r-- | actionpack/test/controller/caching_test.rb | 1 | ||||
-rw-r--r-- | actionpack/test/controller/mime_responds_test.rb | 17 | ||||
-rw-r--r-- | actionpack/test/controller/render_test.rb | 2 | ||||
-rw-r--r-- | actionpack/test/controller/routing_test.rb | 12 | ||||
-rw-r--r-- | actionpack/test/lib/controller/fake_controllers.rb | 13 | ||||
-rw-r--r-- | actionpack/test/template/ajax_test.rb | 12 |
15 files changed, 123 insertions, 118 deletions
diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec index 936279ad12..e191a12997 100644 --- a/actionpack/actionpack.gemspec +++ b/actionpack/actionpack.gemspec @@ -18,7 +18,7 @@ Gem::Specification.new do |s| s.add_dependency('activemodel', '= 3.0.pre') s.add_dependency('rack', '~> 1.0.1') s.add_dependency('rack-test', '~> 0.5.0') - s.add_dependency('rack-mount', '~> 0.2.3') + s.add_dependency('rack-mount', '~> 0.3.0') s.add_dependency('erubis', '~> 2.6.5') s.require_path = 'lib' diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index c251d79f4e..0c264fcd09 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -46,11 +46,8 @@ module ActionController cattr_accessor :use_accept_header self.use_accept_header = true - cattr_accessor :page_cache_directory self.page_cache_directory = defined?(Rails.public_path) ? Rails.public_path : "" - cattr_reader :cache_store - cattr_accessor :consider_all_requests_local self.consider_all_requests_local = true @@ -116,7 +113,7 @@ module ActionController details[:prefix] = nil if name =~ /\blayouts/ super end - + # Move this into a "don't run in production" module def _default_layout(details, require_layout = false) super diff --git a/actionpack/lib/action_controller/metal/responder.rb b/actionpack/lib/action_controller/metal/responder.rb index e8e88e7479..6c76c57839 100644 --- a/actionpack/lib/action_controller/metal/responder.rb +++ b/actionpack/lib/action_controller/metal/responder.rb @@ -102,9 +102,14 @@ module ActionController #:nodoc: # not defined, call to_format. # def self.call(*args) - responder = new(*args) - method = :"to_#{responder.format}" - responder.respond_to?(method) ? responder.send(method) : responder.to_format + new(*args).respond + end + + # Main entry point for responder responsible to dispatch to the proper format. + # + def respond + method = :"to_#{format}" + respond_to?(method) ? send(method) : to_format end # HTML format does not render the resource, it always attempt to render a diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index b3ed7c9d1a..4f35a00247 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -33,7 +33,6 @@ module ActionDispatch # :nodoc: # end class Response < Rack::Response attr_accessor :request, :blank - attr_reader :cache_control attr_writer :header, :sending_file alias_method :headers=, :header= @@ -57,12 +56,6 @@ module ActionDispatch # :nodoc: @cache_control ||= {} end - def write(str) - s = str.to_s - @writer.call s - str - end - def status=(status) @status = status.to_i end @@ -277,7 +270,7 @@ module ActionDispatch # :nodoc: max_age = control[:max_age] options = [] - options << "max-age=#{max_age}" if max_age + options << "max-age=#{max_age.to_i}" if max_age options << (control[:public] ? "public" : "private") options << "must-revalidate" if control[:must_revalidate] options.concat(extras) if extras diff --git a/actionpack/lib/action_dispatch/routing.rb b/actionpack/lib/action_dispatch/routing.rb index 9b977800b4..e99f979197 100644 --- a/actionpack/lib/action_dispatch/routing.rb +++ b/actionpack/lib/action_dispatch/routing.rb @@ -266,77 +266,9 @@ module ActionDispatch SEPARATORS = %w( / . ? ) HTTP_METHODS = [:get, :head, :post, :put, :delete, :options] - # The root paths which may contain controller files - mattr_accessor :controller_paths - self.controller_paths = [] - # A helper module to hold URL related helpers. module Helpers include ActionController::PolymorphicRoutes end - - class << self - def controller_constraints - @controller_constraints ||= Regexp.union(*possible_controllers.collect { |n| Regexp.escape(n) }) - end - - def clear_controller_cache! - @controller_constraints = nil - end - - private - # Returns the array of controller names currently available to ActionController::Routing. - def possible_controllers - possible_controllers = [] - - # 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| - next if seen_paths[path.gsub(%r{^\.[/\\]}, "")] - - controller_name = path[(load_path.length + 1)..-1] - - controller_name.gsub!(/_controller\.rb\Z/, '') - possible_controllers << controller_name - end - end - - # remove duplicates - possible_controllers.uniq! - - possible_controllers - 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 } - 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 dd76391870..8ce6b2f6d5 100644 --- a/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb +++ b/actionpack/lib/action_dispatch/routing/deprecated_mapper.rb @@ -113,7 +113,7 @@ module ActionDispatch end end - requirements[:controller] ||= Routing.controller_constraints + requirements[:controller] ||= @set.controller_constraints if defaults[:controller] defaults[:action] ||= 'index' @@ -175,7 +175,7 @@ module ActionDispatch optional = false elsif segment =~ /^:(\w+)$/ if defaults.has_key?($1.to_sym) - defaults.delete($1.to_sym) + defaults.delete($1.to_sym) if defaults[$1.to_sym].nil? else optional = false end diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 34d75e55b6..400039353c 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -383,7 +383,7 @@ module ActionDispatch constraints.reject! { |k, v| segment_keys.include?(k.to_s) } conditions.merge!(constraints) - requirements[:controller] ||= Routing.controller_constraints + requirements[:controller] ||= @set.controller_constraints if via = options[:via] via = Array(via).map { |m| m.to_s.upcase } diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 79e15edeaa..a8073c2105 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -27,10 +27,13 @@ module ActionDispatch end end + unless controller = controller(params) + return [417, {}, []] + end + if env['action_controller.recognize'] [200, {}, params] else - controller = controller(params) controller.action(params[:action]).call(env) end end @@ -41,6 +44,8 @@ module ActionDispatch controller = "#{params[:controller].camelize}Controller" ActiveSupport::Inflector.constantize(controller) end + rescue NameError + nil end def merge_default_action!(params) @@ -197,10 +202,11 @@ module ActionDispatch end end - attr_accessor :routes, :named_routes, :configuration_files + attr_accessor :routes, :named_routes, :configuration_files, :controller_paths def initialize self.configuration_files = [] + self.controller_paths = [] self.routes = [] self.named_routes = NamedRouteCollection.new @@ -247,7 +253,7 @@ module ActionDispatch def load! # Clear the controller cache so we may discover new ones - Routing.clear_controller_cache! + @controller_constraints = nil load_routes! end @@ -292,6 +298,37 @@ module ActionDispatch routes_changed_at end + CONTROLLER_REGEXP = /[_a-zA-Z0-9]+/ + + def controller_constraints + @controller_constraints ||= begin + source = controller_namespaces.map { |ns| "#{Regexp.escape(ns)}/#{CONTROLLER_REGEXP.source}" } + source << CONTROLLER_REGEXP.source + Regexp.compile(source.sort.reverse.join('|')) + end + end + + def controller_namespaces + namespaces = Set.new + + # Find any nested controllers already in memory + ActionController::Base.subclasses.each do |klass| + controller_name = klass.underscore + namespaces << controller_name.split('/')[0...-1].join('/') + end + + # Find namespaces in controllers/ directory + controller_paths.each do |load_path| + load_path = File.expand_path(load_path) + Dir["#{load_path}/**/*_controller.rb"].collect do |path| + namespaces << File.dirname(path).sub(/#{load_path}\/?/, '') + end + end + + namespaces.delete('') + namespaces + end + def add_route(app, conditions = {}, requirements = {}, defaults = {}, name = nil) route = Route.new(app, conditions, requirements, defaults, name) @set.add_route(*route) @@ -374,7 +411,8 @@ module ActionDispatch end recall[:action] = options.delete(:action) if options[:action] == 'index' - parameterize = lambda { |name, value| + opts = {} + opts[:parameterize] = lambda { |name, value| if name == :controller value elsif value.is_a?(Array) @@ -384,7 +422,22 @@ module ActionDispatch end } - path = @set.url(named_route, options, recall, :parameterize => parameterize) + unless result = @set.generate(:path_info, named_route, options, recall, opts) + raise ActionController::RoutingError, "No route matches #{options.inspect}" + end + + uri, params = result + params.each do |k, v| + if v + params[k] = v + else + params.delete(k) + end + end + + uri << "?#{params.to_query}" if uri && params.any? + path = uri + if path && method == :generate_extras uri = URI(path) extras = uri.query ? diff --git a/actionpack/lib/action_view/render/partials.rb b/actionpack/lib/action_view/render/partials.rb index 2eb88ae3e5..aeaf1ee4ff 100644 --- a/actionpack/lib/action_view/render/partials.rb +++ b/actionpack/lib/action_view/render/partials.rb @@ -181,20 +181,20 @@ module ActionView def initialize(view_context, options, block) @view = view_context @partial_names = PARTIAL_NAMES[@view.controller.class] - + key = Thread.current[:format_locale_key] @templates = TEMPLATES[key] if key - + setup(options, block) end - + def setup(options, block) partial = options[:partial] - + @options = options @locals = options[:locals] || {} @block = block - + if String === partial @object = options[:object] @path = partial @@ -240,7 +240,7 @@ module ActionView segments << template.render(@view, locals) end - + @template = template segments end @@ -294,7 +294,7 @@ module ActionView path && @templates[path] ||= _find_template(path) end end - + def _find_template(path) if controller = @view.controller prefix = controller.controller_path unless path.include?(?/) @@ -319,7 +319,7 @@ module ActionView _evaluate_assigns_and_ivars details = options[:_details] - + # Is this needed self.formats = details[:formats] if details renderer = PartialRenderer.new(self, options, nil) @@ -329,12 +329,12 @@ module ActionView end def _render_partial(options, &block) #:nodoc: - if @renderer + if defined? @renderer @renderer.setup(options, block) else @renderer = PartialRenderer.new(self, options, block) end - + @renderer.render end diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 54de920740..682a8f3995 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -640,6 +640,7 @@ class FragmentCachingTest < ActionController::TestCase assert fragment_computed assert_equal 'generated till now -> ', buffer + ActiveSupport::Notifications.notifier.wait assert_equal [:fragment_exist?, :write_fragment], events.map(&:first) end diff --git a/actionpack/test/controller/mime_responds_test.rb b/actionpack/test/controller/mime_responds_test.rb index fee9cf46f9..c1fa74b8c8 100644 --- a/actionpack/test/controller/mime_responds_test.rb +++ b/actionpack/test/controller/mime_responds_test.rb @@ -507,6 +507,13 @@ class RespondWithController < ActionController::Base end end + def using_responder_with_respond + responder = Class.new(ActionController::Responder) do + def respond; @controller.render :text => "respond #{format}"; end + end + respond_with(Customer.new("david", 13), :responder => responder) + end + protected def _render_js(js, options) @@ -735,6 +742,16 @@ class RespondWithControllerTest < ActionController::TestCase assert_equal "foo - #{[:html].to_s}", @controller.response_body end + def test_respond_as_responder_entry_point + @request.accept = "text/html" + get :using_responder_with_respond + assert_equal "respond html", @response.body + + @request.accept = "application/xml" + get :using_responder_with_respond + assert_equal "respond xml", @response.body + end + def test_clear_respond_to @controller = InheritedRespondWithController.new @request.accept = "text/html" diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index b32325fa20..cffa970011 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -54,7 +54,7 @@ class TestController < ActionController::Base end def conditional_hello_with_expires_in - expires_in 1.minute + expires_in 60.1.seconds render :action => 'hello_world' end diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb index b5effeda40..b83c5792ba 100644 --- a/actionpack/test/controller/routing_test.rb +++ b/actionpack/test/controller/routing_test.rb @@ -1621,7 +1621,7 @@ class RouteSetTest < ActiveSupport::TestCase end def test_expand_array_build_query_string - assert_uri_equal '/foo?x%5B%5D=1&x%5B%5D=2', default_route_set.generate({:controller => 'foo', :x => [1, 2]}) + assert_uri_equal '/foo?x[]=1&x[]=2', default_route_set.generate({:controller => 'foo', :x => [1, 2]}) end def test_escape_spaces_build_query_string_selected_keys @@ -1639,9 +1639,7 @@ class RouteSetTest < ActiveSupport::TestCase map.connect ':controller/:action/:id' end - pending do - assert_equal '/ibocorp', set.generate({:controller => 'ibocorp', :page => 1}) - end + assert_equal '/ibocorp', set.generate({:controller => 'ibocorp', :page => 1}) end def test_generate_with_optional_params_recalls_last_request @@ -1853,11 +1851,9 @@ class RackMountIntegrationTests < ActiveSupport::TestCase assert_equal({:controller => 'posts', :action => 'show_date', :year => '2009'}, @routes.recognize_path('/blog/2009', :method => :get)) assert_equal({:controller => 'posts', :action => 'show_date', :year => '2009', :month => '01'}, @routes.recognize_path('/blog/2009/01', :method => :get)) assert_equal({:controller => 'posts', :action => 'show_date', :year => '2009', :month => '01', :day => '01'}, @routes.recognize_path('/blog/2009/01/01', :method => :get)) - assert_raise(ActionController::ActionControllerError) { @routes.recognize_path('/blog/123456789', :method => :get) } assert_equal({:controller => 'archive', :action => 'index', :year => '2010'}, @routes.recognize_path('/archive/2010')) assert_equal({:controller => 'archive', :action => 'index'}, @routes.recognize_path('/archive')) - assert_raise(ActionController::ActionControllerError) { @routes.recognize_path('/archive/january') } assert_equal({:controller => 'people', :action => 'index'}, @routes.recognize_path('/people', :method => :get)) assert_equal({:controller => 'people', :action => 'index', :format => 'xml'}, @routes.recognize_path('/people.xml', :method => :get)) @@ -2016,9 +2012,9 @@ class RackMountIntegrationTests < ActiveSupport::TestCase assert_equal '/posts', @routes.generate({:controller => 'posts'}, {:controller => 'posts', :action => 'index'}) assert_equal '/posts/create', @routes.generate({:action => 'create'}, {:controller => 'posts'}) assert_equal '/posts?foo=bar', @routes.generate(:controller => 'posts', :foo => 'bar') - assert_equal '/posts?foo%5B%5D=bar&foo%5B%5D=baz', @routes.generate(:controller => 'posts', :foo => ['bar', 'baz']) + assert_equal '/posts?foo[]=bar&foo[]=baz', @routes.generate(:controller => 'posts', :foo => ['bar', 'baz']) assert_equal '/posts?page=2', @routes.generate(:controller => 'posts', :page => 2) - assert_equal '/posts?q%5Bfoo%5D%5Ba%5D=b', @routes.generate(:controller => 'posts', :q => { :foo => { :a => 'b'}}) + assert_equal '/posts?q[foo][a]=b', @routes.generate(:controller => 'posts', :q => { :foo => { :a => 'b'}}) assert_equal '/', @routes.generate(:controller => 'news', :action => 'index') assert_equal '/', @routes.generate(:controller => 'news', :action => 'index', :format => nil) diff --git a/actionpack/test/lib/controller/fake_controllers.rb b/actionpack/test/lib/controller/fake_controllers.rb index 250327e6dc..09692f77b5 100644 --- a/actionpack/test/lib/controller/fake_controllers.rb +++ b/actionpack/test/lib/controller/fake_controllers.rb @@ -1,37 +1,48 @@ class << Object; alias_method :const_available?, :const_defined?; end class ContentController < ActionController::Base; end -class NotAController; end module Admin class << self; alias_method :const_available?, :const_defined?; end + class AccountsController < ActionController::Base; end class NewsFeedController < ActionController::Base; end class PostsController < ActionController::Base; end class StuffController < ActionController::Base; end class UserController < ActionController::Base; end + class UsersController < ActionController::Base; end end module Api + class UsersController < ActionController::Base; end class ProductsController < ActionController::Base; end end # TODO: Reduce the number of test controllers we use +class AccountController < ActionController::Base; end class AddressesController < ActionController::Base; end +class ArchiveController < ActionController::Base; end class ArticlesController < ActionController::Base; end class BarController < ActionController::Base; end +class BlogController < ActionController::Base; end class BooksController < ActionController::Base; end class BraveController < ActionController::Base; end +class CarsController < ActionController::Base; end +class CcController < ActionController::Base; end class CController < ActionController::Base; end class ElsewhereController < ActionController::Base; end class FooController < ActionController::Base; end +class GeocodeController < ActionController::Base; end class HiController < ActionController::Base; end class ImageController < ActionController::Base; end +class NewsController < ActionController::Base; end class NotesController < ActionController::Base; end class PeopleController < ActionController::Base; end class PostsController < ActionController::Base; end class SessionsController < ActionController::Base; end class StuffController < ActionController::Base; end class SubpathBooksController < ActionController::Base; end +class SymbolsController < ActionController::Base; end +class UserController < ActionController::Base; end class WeblogController < ActionController::Base; end # For speed test diff --git a/actionpack/test/template/ajax_test.rb b/actionpack/test/template/ajax_test.rb index 670ba92697..aeb7c09b09 100644 --- a/actionpack/test/template/ajax_test.rb +++ b/actionpack/test/template/ajax_test.rb @@ -6,7 +6,7 @@ class AjaxTestCase < ActiveSupport::TestCase def assert_html(html, matches) matches.each do |match| - assert_match Regexp.new(Regexp.escape(match)), html + assert_match(Regexp.new(Regexp.escape(match)), html) end end @@ -52,18 +52,18 @@ class LinkToRemoteTest < AjaxTestCase test "with a hash for :update" do link = link(:update => {:success => "#posts", :failure => "#error"}) - assert_match /data-update-success="#posts"/, link - assert_match /data-update-failure="#error"/, link + assert_match(/data-update-success="#posts"/, link) + assert_match(/data-update-failure="#error"/, link) end test "with positional parameters" do link = link(:position => :top, :update => "#posts") - assert_match /data\-update\-position="top"/, link + assert_match(/data\-update\-position="top"/, link) end test "with an optional method" do link = link(:method => "delete") - assert_match /data-method="delete"/, link + assert_match(/data-method="delete"/, link) end class LegacyLinkToRemoteTest < AjaxTestCase @@ -99,7 +99,7 @@ class ButtonToRemoteTest < AjaxTestCase button = button({:url => {:action => "whatnot"}}, {:class => "fine"}) [/input/, /class="fine"/, /type="button"/, /value="Remote outpost"/, /data-url="\/whatnot"/].each do |match| - assert_match match, button + assert_match(match, button) end end end |