diff options
author | José Valim <jose.valim@gmail.com> | 2009-12-25 12:09:13 +0100 |
---|---|---|
committer | José Valim <jose.valim@gmail.com> | 2009-12-25 12:09:13 +0100 |
commit | eb8e627c6918dae53c7ab8b9208e72ff64d20348 (patch) | |
tree | 4f153960d158c119ebdcef7a3a02c407e4b82dd0 | |
parent | 4b8330d2d50ae4de14dd43ffbea4d91804553140 (diff) | |
parent | 1c66f85eb6cd80053cf60889634a8c39c21b11a1 (diff) | |
download | rails-eb8e627c6918dae53c7ab8b9208e72ff64d20348.tar.gz rails-eb8e627c6918dae53c7ab8b9208e72ff64d20348.tar.bz2 rails-eb8e627c6918dae53c7ab8b9208e72ff64d20348.zip |
Merge branch 'master' of git://github.com/rails/rails
81 files changed, 960 insertions, 915 deletions
@@ -13,7 +13,8 @@ gem "pg", ">= 0.8.0" gem "mysql", ">= 2.8.1" # AP -gem "rack", "1.0.1", :git => "git://github.com/rails/rack.git" +gem "rack", "1.1.0", :git => "git://github.com/rack/rack.git" +gem "rack-test", "0.5.3" gem "RedCloth", ">= 4.2.2" if ENV['CI'] @@ -30,3 +31,5 @@ if ENV['CI'] gem "test-unit", ">= 2.0.5" end end + +disable_system_gems
\ No newline at end of file diff --git a/actionmailer/lib/action_mailer.rb b/actionmailer/lib/action_mailer.rb index f439eb175c..d7bbbbd78c 100644 --- a/actionmailer/lib/action_mailer.rb +++ b/actionmailer/lib/action_mailer.rb @@ -41,18 +41,3 @@ module ActionMailer autoload :TestHelper autoload :Utils end - -module Text - extend ActiveSupport::Autoload - - autoload :Format, 'action_mailer/vendor/text_format' -end - -module Net - extend ActiveSupport::Autoload - - autoload :SMTP -end - - -require 'action_mailer/vendor/tmail' diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 40aff7f0d8..de78e87fb4 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -1,4 +1,7 @@ require 'active_support/core_ext/class' +require 'action_mailer/part' +require 'action_mailer/vendor/text_format' +require 'action_mailer/vendor/tmail' module ActionMailer #:nodoc: # Action Mailer allows you to send email from your application using a mailer model and views. @@ -250,31 +253,21 @@ module ActionMailer #:nodoc: # <tt>["text/html", "text/enriched", "text/plain"]</tt>. Items that appear first in the array have higher priority in the mail client # and appear last in the mime encoded message. You can also pick a different order from inside a method with # +implicit_parts_order+. - class Base + class Base < AbstractController::Base include AdvAttrAccessor, PartContainer, Quoting, Utils include AbstractController::Rendering include AbstractController::LocalizedCache include AbstractController::Layouts - include AbstractController::Helpers - helper ActionMailer::MailHelper - if Object.const_defined?(:ActionController) - include ActionController::UrlWriter - end + helper ActionMailer::MailHelper + include ActionController::UrlWriter include ActionMailer::DeprecatedBody private_class_method :new #:nodoc: - class_inheritable_accessor :view_paths - self.view_paths = [] - - attr_internal :formats - - cattr_accessor :logger - @@raise_delivery_errors = true cattr_accessor :raise_delivery_errors @@ -346,24 +339,13 @@ module ActionMailer #:nodoc: # have multiple mailer methods share the same template. adv_attr_accessor :template - # The mail and action_name instances referenced by this mailer. - attr_reader :mail, :action_name - - # Where the response body is stored. - attr_internal :response_body - # Override the mailer name, which defaults to an inflected version of the # mailer's class name. If you want to use a template in a non-standard # location, you can use this to specify that location. - attr_writer :mailer_name + adv_attr_accessor :mailer_name - def mailer_name(value = nil) - if value - @mailer_name = value - else - @mailer_name || self.class.mailer_name - end - end + # Expose the internal mail + attr_reader :mail # Alias controller_path to mailer_name so render :partial in views work. alias :controller_path :mailer_name @@ -453,18 +435,16 @@ module ActionMailer #:nodoc: # will be initialized according to the named method. If not, the mailer will # remain uninitialized (useful when you only need to invoke the "receive" # method, for instance). - def initialize(method_name=nil, *parameters) #:nodoc: - @_formats = [] - @_response_body = nil + def initialize(method_name=nil, *args) #:nodoc: super() - create!(method_name, *parameters) if method_name + process(method_name, *args) if method_name end - # Initialize the mailer via the given +method_name+. The body will be + # Process the mailer via the given +method_name+. The body will be # rendered and a new TMail::Mail object created. - def create!(method_name, *parameters) #:nodoc: + def process(method_name, *args) #:nodoc: initialize_defaults(method_name) - __send__(method_name, *parameters) + super # Create e-mail parts create_parts @@ -473,7 +453,7 @@ module ActionMailer #:nodoc: @subject ||= I18n.t(:subject, :scope => [:actionmailer, mailer_name, method_name], :default => method_name.humanize) - # build the mail object itself + # Build the mail object itself @mail = create_mail end @@ -488,7 +468,7 @@ module ActionMailer #:nodoc: logger.debug "\n#{mail.encoded}" end - ActiveSupport::Notifications.instrument(:deliver_mail, :mail => @mail) do + ActiveSupport::Notifications.instrument(:deliver_mail, :mail => mail) do begin self.delivery_method.perform_delivery(mail) if perform_deliveries rescue Exception => e # Net::SMTP errors or sendmail pipe errors @@ -510,23 +490,18 @@ module ActionMailer #:nodoc: @implicit_parts_order ||= @@default_implicit_parts_order.dup @mime_version ||= @@default_mime_version.dup if @@default_mime_version - @mailer_name ||= self.class.mailer_name + @mailer_name ||= self.class.mailer_name.dup @template ||= method_name - @action_name = @template @parts ||= [] @headers ||= {} @sent_on ||= Time.now - ActiveSupport::Deprecation.silence do - super # Run deprecation hooks - end + super # Run deprecation hooks end def create_parts - ActiveSupport::Deprecation.silence do - super # Run deprecation hooks - end + super # Run deprecation hooks if String === response_body @parts.unshift Part.new( diff --git a/actionmailer/lib/action_mailer/delivery_method.rb b/actionmailer/lib/action_mailer/delivery_method.rb index 29a51afdc3..4f7d3afc3c 100644 --- a/actionmailer/lib/action_mailer/delivery_method.rb +++ b/actionmailer/lib/action_mailer/delivery_method.rb @@ -1,7 +1,7 @@ -require "active_support/core_ext/class" +require 'active_support/core_ext/class' + module ActionMailer module DeliveryMethod - autoload :File, 'action_mailer/delivery_method/file' autoload :Sendmail, 'action_mailer/delivery_method/sendmail' autoload :Smtp, 'action_mailer/delivery_method/smtp' @@ -52,6 +52,5 @@ module ActionMailer superclass_delegating_accessor :settings self.settings = {} end - end end diff --git a/actionmailer/lib/action_mailer/delivery_method/smtp.rb b/actionmailer/lib/action_mailer/delivery_method/smtp.rb index 95c117c9e0..f81d64af36 100644 --- a/actionmailer/lib/action_mailer/delivery_method/smtp.rb +++ b/actionmailer/lib/action_mailer/delivery_method/smtp.rb @@ -1,8 +1,9 @@ +require 'net/smtp' + module ActionMailer module DeliveryMethod # A delivery method implementation which sends via smtp. class Smtp < Method - self.settings = { :address => "localhost", :port => 25, @@ -26,6 +27,5 @@ module ActionMailer end end end - end end diff --git a/actionmailer/lib/action_mailer/rails.rb b/actionmailer/lib/action_mailer/rails.rb new file mode 100644 index 0000000000..a3573cdea7 --- /dev/null +++ b/actionmailer/lib/action_mailer/rails.rb @@ -0,0 +1,24 @@ +require "action_mailer" + +module ActionMailer + class Plugin < Rails::Plugin + plugin_name :action_mailer + + initializer "action_mailer.set_configs" do |app| + app.config.action_mailer.each do |k,v| + ActionMailer::Base.send "#{k}=", v + end + end + + # TODO: ActionController::Base.logger should delegate to its own config.logger + initializer "action_mailer.logger" do + ActionMailer::Base.logger ||= Rails.logger + end + + initializer "action_mailer.view_paths" do |app| + # TODO: this should be combined with the logic for default config.action_mailer.view_paths + view_path = ActionView::PathSet.type_cast(app.config.view_path, app.config.cache_classes) + ActionMailer::Base.template_root = view_path if ActionMailer::Base.view_paths.blank? + end + end +end
\ No newline at end of file diff --git a/actionmailer/test/mail_service_test.rb b/actionmailer/test/mail_service_test.rb index 697265b8ec..1cd3bc77c4 100644 --- a/actionmailer/test/mail_service_test.rb +++ b/actionmailer/test/mail_service_test.rb @@ -34,13 +34,13 @@ class TestMailer < ActionMailer::Base def from_with_name from "System <system@loudthinking.com>" recipients "root@loudthinking.com" - body "Nothing to see here." + render :text => "Nothing to see here." end def from_without_name from "system@loudthinking.com" recipients "root@loudthinking.com" - body "Nothing to see here." + render :text => "Nothing to see here." end def cc_bcc(recipient) @@ -301,6 +301,7 @@ class TestMailer < ActionMailer::Base render :text => "testing" end + # This tests body calls accepeting a hash, which is deprecated. def body_ivar(recipient) recipients recipient subject "Body as a local variable" @@ -1043,7 +1044,8 @@ EOF end def test_body_is_stored_as_an_ivar - mail = TestMailer.create_body_ivar(@recipient) + mail = nil + ActiveSupport::Deprecation.silence { mail = TestMailer.create_body_ivar(@recipient) } assert_equal "body: foo\nbar: baz", mail.body end diff --git a/actionmailer/test/url_test.rb b/actionmailer/test/url_test.rb index 18eb355e7d..1140613132 100644 --- a/actionmailer/test/url_test.rb +++ b/actionmailer/test/url_test.rb @@ -12,8 +12,8 @@ class TestMailer < ActionMailer::Base @from = "system@loudthinking.com" @sent_on = Time.local(2004, 12, 12) - @body["recipient"] = recipient - @body["welcome_url"] = url_for :host => "example.com", :controller => "welcome", :action => "greeting" + @recipient = recipient + @welcome_url = url_for :host => "example.com", :controller => "welcome", :action => "greeting" end class <<self diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec index 23d478fd44..ab9c7f9c35 100644 --- a/actionpack/actionpack.gemspec +++ b/actionpack/actionpack.gemspec @@ -16,9 +16,9 @@ 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.1') + s.add_dependency('rack', '~> 1.1.0') s.add_dependency('rack-test', '~> 0.5.0') - s.add_dependency('rack-mount', '~> 0.3.2') + s.add_dependency('rack-mount', '~> 0.3.3') s.add_dependency('erubis', '~> 2.6.5') s.require_path = 'lib' diff --git a/actionpack/lib/abstract_controller.rb b/actionpack/lib/abstract_controller.rb index c15a1da98a..237ab577ba 100644 --- a/actionpack/lib/abstract_controller.rb +++ b/actionpack/lib/abstract_controller.rb @@ -8,13 +8,11 @@ require 'active_support/core_ext/module/delegation' module AbstractController extend ActiveSupport::Autoload - deferrable do - autoload :Base - autoload :Callbacks - autoload :Helpers - autoload :Layouts - autoload :LocalizedCache - autoload :Logger - autoload :Rendering - end + autoload :Base + autoload :Callbacks + autoload :Helpers + autoload :Layouts + autoload :LocalizedCache + autoload :Logger + autoload :Rendering end diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index 9d57c52429..efea81aa71 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -84,7 +84,7 @@ module AbstractController # # ==== Returns # self - def process(action) + def process(action, *args) @_action_name = action_name = action.to_s unless action_name = method_for_action(action_name) @@ -93,7 +93,7 @@ module AbstractController @_response_body = nil - process_action(action_name) + process_action(action_name, *args) end private @@ -113,8 +113,8 @@ module AbstractController # Call the action. Override this in a subclass to modify the # behavior around processing an action. This, and not #process, # is the intended way to override action dispatching. - def process_action(method_name) - send_action(method_name) + def process_action(method_name, *args) + send_action(method_name, *args) end # Actually call the method associated with the action. Override diff --git a/actionpack/lib/abstract_controller/logger.rb b/actionpack/lib/abstract_controller/logger.rb index 27ba5be45f..e3bcd28da7 100644 --- a/actionpack/lib/abstract_controller/logger.rb +++ b/actionpack/lib/abstract_controller/logger.rb @@ -29,33 +29,5 @@ module AbstractController @str.send(*args, &block) end end - - # Override process_action in the AbstractController::Base - # to log details about the method. - def process_action(action) - result = ActiveSupport::Notifications.instrument(:process_action, - :controller => self, :action => action) do - super - end - - if logger - log = DelayedLog.new do - "\n\nProcessing #{self.class.name}\##{action_name} " \ - "to #{request.formats} (for #{request_origin}) " \ - "[#{request.method.to_s.upcase}]" - end - - logger.info(log) - end - - result - end - - private - # Returns the request origin with the IP and time. This needs to be cached, - # otherwise we would get different results for each time it calls. - def request_origin - @request_origin ||= "#{request.remote_ip} at #{Time.now.to_s(:db)}" - end end end diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index e31b795cd2..26a85d4de8 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -5,65 +5,66 @@ require 'active_support/ruby/shim' module ActionController extend ActiveSupport::Autoload - deferrable do - autoload :Base - autoload :Caching - autoload :PolymorphicRoutes - autoload :Translation - autoload :Metal - autoload :Middleware + autoload :Base + autoload :Caching + autoload :PolymorphicRoutes + autoload :Translation + autoload :Metal + autoload :Middleware - autoload_under "metal" do - autoload :Benchmarking - autoload :ConditionalGet - autoload :Configuration - autoload :Head - autoload :Helpers - autoload :HideActions - autoload :Layouts - autoload :MimeResponds - autoload :RackDelegation - autoload :Compatibility - autoload :Redirecting - autoload :Rendering - autoload :Renderers - autoload :Rescue - autoload :Responder - autoload :SessionManagement - autoload :UrlFor - autoload :Verification - autoload :Flash - autoload :RequestForgeryProtection - autoload :Streaming - autoload :HttpAuthentication - autoload :FilterParameterLogging - autoload :Cookies - end - - autoload :Dispatcher, 'action_controller/dispatch/dispatcher' - autoload :PerformanceTest, 'action_controller/deprecated/performance_test' - autoload :Routing, 'action_controller/deprecated' - autoload :Integration, 'action_controller/deprecated/integration_test' - autoload :IntegrationTest, 'action_controller/deprecated/integration_test' + autoload_under "metal" do + autoload :Benchmarking + autoload :ConditionalGet + autoload :Configuration + autoload :Head + autoload :Helpers + autoload :HideActions + autoload :Layouts + autoload :Logger + autoload :MimeResponds + autoload :RackDelegation + autoload :Compatibility + autoload :Redirecting + autoload :Rendering + autoload :Renderers + autoload :Rescue + autoload :Responder + autoload :SessionManagement + autoload :UrlFor + autoload :Verification + autoload :Flash + autoload :RequestForgeryProtection + autoload :Streaming + autoload :HttpAuthentication + autoload :FilterParameterLogging + autoload :Cookies end - autoload :RecordIdentifier - autoload :UrlRewriter - autoload :UrlWriter, 'action_controller/url_rewriter' + autoload :Dispatcher, 'action_controller/dispatch/dispatcher' + autoload :PerformanceTest, 'action_controller/deprecated/performance_test' + autoload :Routing, 'action_controller/deprecated' + autoload :Integration, 'action_controller/deprecated/integration_test' + autoload :IntegrationTest, 'action_controller/deprecated/integration_test' - # TODO: Don't autoload exceptions, setup explicit - # requires for files that need them - autoload_at "action_controller/metal/exceptions" do - autoload :ActionControllerError - autoload :RenderError - autoload :RoutingError - autoload :MethodNotAllowed - autoload :NotImplemented - autoload :UnknownController - autoload :MissingFile - autoload :RenderError - autoload :SessionOverflowError - autoload :UnknownHttpMethod + eager_autoload do + autoload :RecordIdentifier + autoload :UrlRewriter + autoload :UrlWriter, 'action_controller/url_rewriter' + + # TODO: Don't autoload exceptions, setup explicit + # requires for files that need them + autoload_at "action_controller/metal/exceptions" do + autoload :ActionControllerError + autoload :RenderError + autoload :RoutingError + autoload :MethodNotAllowed + autoload :NotImplemented + autoload :UnknownController + autoload :MissingFile + autoload :RenderError + autoload :SessionOverflowError + autoload :UnknownHttpMethod + end end end diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 452f0cd4f0..dbba69f637 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -14,6 +14,7 @@ module ActionController include ActionController::Layouts include ActionController::ConditionalGet include ActionController::RackDelegation + include ActionController::Logger include ActionController::Benchmarking include ActionController::Configuration @@ -89,7 +90,7 @@ module ActionController end if options[:status] - options[:status] = ActionDispatch::StatusCodes[options[:status]] + options[:status] = Rack::Utils.status_code(options[:status]) end options[:update] = blk if block_given? diff --git a/actionpack/lib/action_controller/caching.rb b/actionpack/lib/action_controller/caching.rb index ad357cceda..d784138ebe 100644 --- a/actionpack/lib/action_controller/caching.rb +++ b/actionpack/lib/action_controller/caching.rb @@ -32,11 +32,13 @@ module ActionController #:nodoc: extend ActiveSupport::Concern extend ActiveSupport::Autoload - autoload :Actions - autoload :Fragments - autoload :Pages - autoload :Sweeper, 'action_controller/caching/sweeping' - autoload :Sweeping, 'action_controller/caching/sweeping' + eager_autoload do + autoload :Actions + autoload :Fragments + autoload :Pages + autoload :Sweeper, 'action_controller/caching/sweeping' + autoload :Sweeping, 'action_controller/caching/sweeping' + end included do @@cache_store = nil diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb index 93a19f8f93..b436de9878 100644 --- a/actionpack/lib/action_controller/metal.rb +++ b/actionpack/lib/action_controller/metal.rb @@ -69,7 +69,7 @@ module ActionController end def status=(status) - @_status = ActionDispatch::StatusCodes[status] + @_status = Rack::Utils.status_code(status) end # :api: private diff --git a/actionpack/lib/action_controller/metal/benchmarking.rb b/actionpack/lib/action_controller/metal/benchmarking.rb index e58df69172..f73f635b0d 100644 --- a/actionpack/lib/action_controller/metal/benchmarking.rb +++ b/actionpack/lib/action_controller/metal/benchmarking.rb @@ -53,7 +53,6 @@ module ActionController #:nodoc: log_message << " [#{complete_request_uri rescue "unknown"}]" logger.info(log_message) - response.headers["X-Runtime"] = "%.0f" % ms else super end diff --git a/actionpack/lib/action_controller/metal/logger.rb b/actionpack/lib/action_controller/metal/logger.rb new file mode 100644 index 0000000000..956d7dd371 --- /dev/null +++ b/actionpack/lib/action_controller/metal/logger.rb @@ -0,0 +1,34 @@ +require 'abstract_controller/logger' + +module ActionController + module Logger + # Override process_action in the AbstractController::Base + # to log details about the method. + def process_action(action) + result = ActiveSupport::Notifications.instrument(:process_action, + :controller => self, :action => action) do + super + end + + if logger + log = AbstractController::Logger::DelayedLog.new do + "\n\nProcessing #{self.class.name}\##{action_name} " \ + "to #{request.formats} (for #{request_origin}) " \ + "[#{request.method.to_s.upcase}]" + end + + logger.info(log) + end + + result + end + + private + + # Returns the request origin with the IP and time. This needs to be cached, + # otherwise we would get different results for each time it calls. + def request_origin + @request_origin ||= "#{request.remote_ip} at #{Time.now.to_s(:db)}" + end + end +end diff --git a/actionpack/lib/action_controller/metal/rack_delegation.rb b/actionpack/lib/action_controller/metal/rack_delegation.rb index 833475cff7..bb55383631 100644 --- a/actionpack/lib/action_controller/metal/rack_delegation.rb +++ b/actionpack/lib/action_controller/metal/rack_delegation.rb @@ -1,3 +1,6 @@ +require 'action_dispatch/http/request' +require 'action_dispatch/http/response' + module ActionController module RackDelegation extend ActiveSupport::Concern diff --git a/actionpack/lib/action_controller/metal/redirecting.rb b/actionpack/lib/action_controller/metal/redirecting.rb index 39dc23024c..7a2f9a6fc5 100644 --- a/actionpack/lib/action_controller/metal/redirecting.rb +++ b/actionpack/lib/action_controller/metal/redirecting.rb @@ -58,18 +58,18 @@ module ActionController logger.info("Redirected to #{location}") if logger && logger.info? end - + private def _extract_redirect_to_status(options, response_status) status = if options.is_a?(Hash) && options.key?(:status) - ActionDispatch::StatusCodes[options.delete(:status)] + Rack::Utils.status_code(options.delete(:status)) elsif response_status.key?(:status) - ActionDispatch::StatusCodes[response_status[:status]] + Rack::Utils.status_code(response_status[:status]) else 302 end end - + def _compute_redirect_to_location(options) case options # The scheme name consist of a letter followed by any combination of diff --git a/actionpack/lib/action_controller/notifications.rb b/actionpack/lib/action_controller/notifications.rb deleted file mode 100644 index 1a4f29e0e2..0000000000 --- a/actionpack/lib/action_controller/notifications.rb +++ /dev/null @@ -1,10 +0,0 @@ -require 'active_support/notifications' - -ActiveSupport::Notifications.subscribe(/(read|write|cache|expire|exist)_(fragment|page)\??/) do |*args| - event = ActiveSupport::Notifications::Event.new(*args) - - if logger = ActionController::Base.logger - human_name = event.name.to_s.humanize - logger.info("#{human_name} (%.1fms)" % event.duration) - end -end diff --git a/actionpack/lib/action_controller/rails.rb b/actionpack/lib/action_controller/rails.rb new file mode 100644 index 0000000000..36a52b3149 --- /dev/null +++ b/actionpack/lib/action_controller/rails.rb @@ -0,0 +1,102 @@ +module ActionController + class Plugin < Rails::Plugin + plugin_name :action_controller + + initializer "action_controller.set_configs" do |app| + app.config.action_controller.each do |k,v| + ActionController::Base.send "#{k}=", v + end + end + + # TODO: ActionController::Base.logger should delegate to its own config.logger + initializer "action_controller.logger" do + ActionController::Base.logger ||= Rails.logger + end + + # Routing must be initialized after plugins to allow the former to extend the routes + # --- + # If Action Controller is not one of the loaded frameworks (Configuration#frameworks) + # this does nothing. Otherwise, it loads the routing definitions and sets up + # loading module used to lazily load controllers (Configuration#controller_paths). + initializer "action_controller.initialize_routing" do |app| + app.route_configuration_files << app.config.routes_configuration_file + app.route_configuration_files << app.config.builtin_routes_configuration_file + app.reload_routes! + end + + # Include middleware to serve up static assets + initializer "action_controller.initialize_static_server" do |app| + if app.config.serve_static_assets + app.config.middleware.use(ActionDispatch::Static, Rails.public_path) + end + end + + initializer "action_controller.initialize_middleware_stack" do |app| + middleware = app.config.middleware + middleware.use(::Rack::Lock, :if => lambda { ActionController::Base.allow_concurrency }) + middleware.use(::Rack::Runtime) + middleware.use(ActionDispatch::ShowExceptions, lambda { ActionController::Base.consider_all_requests_local }) + middleware.use(ActionDispatch::Callbacks, lambda { ActionController::Dispatcher.prepare_each_request }) + middleware.use(lambda { ActionController::Base.session_store }, lambda { ActionController::Base.session_options }) + middleware.use(ActionDispatch::ParamsParser) + middleware.use(::Rack::MethodOverride) + middleware.use(::Rack::Head) + middleware.use(ActionDispatch::StringCoercion) + end + + initializer "action_controller.initialize_framework_caches" do + ActionController::Base.cache_store ||= RAILS_CACHE + end + + # Sets +ActionController::Base#view_paths+ and +ActionMailer::Base#template_root+ + # (but only for those frameworks that are to be loaded). If the framework's + # paths have already been set, it is not changed, otherwise it is + # set to use Configuration#view_path. + initializer "action_controller.initialize_framework_views" do |app| + # TODO: this should be combined with the logic for default config.action_controller.view_paths + view_path = ActionView::PathSet.type_cast(app.config.view_path, app.config.cache_classes) + ActionController::Base.view_paths = view_path if ActionController::Base.view_paths.blank? + end + + initializer "action_controller.initialize_metal" do |app| + Rails::Rack::Metal.requested_metals = app.config.metals + + app.config.middleware.insert_before(:"ActionDispatch::ParamsParser", + Rails::Rack::Metal, :if => Rails::Rack::Metal.metals.any?) + end + + # # Prepare dispatcher callbacks and run 'prepare' callbacks + initializer "action_controller.prepare_dispatcher" do |app| + # TODO: This used to say unless defined?(Dispatcher). Find out why and fix. + require 'rails/dispatcher' + + Dispatcher.define_dispatcher_callbacks(app.config.cache_classes) + + unless app.config.cache_classes + # Setup dev mode route reloading + routes_last_modified = app.routes_changed_at + reload_routes = lambda do + unless app.routes_changed_at == routes_last_modified + routes_last_modified = app.routes_changed_at + app.reload_routes! + end + end + ActionDispatch::Callbacks.before_dispatch { |callbacks| reload_routes.call } + end + end + + initializer "action_controller.notifications" do |app| + require 'active_support/notifications' + + ActiveSupport::Notifications.subscribe(/(read|write|cache|expire|exist)_(fragment|page)\??/) do |*args| + event = ActiveSupport::Notifications::Event.new(*args) + + if logger = ActionController::Base.logger + human_name = event.name.to_s.humanize + logger.info("#{human_name} (%.1fms)" % event.duration) + end + end + end + + end +end
\ No newline at end of file diff --git a/actionpack/lib/action_controller/vendor/html-scanner.rb b/actionpack/lib/action_controller/vendor/html-scanner.rb index 2cb20ddd05..879b31e60e 100644 --- a/actionpack/lib/action_controller/vendor/html-scanner.rb +++ b/actionpack/lib/action_controller/vendor/html-scanner.rb @@ -3,16 +3,18 @@ $LOAD_PATH << "#{File.dirname(__FILE__)}/html-scanner" module HTML extend ActiveSupport::Autoload - autoload :CDATA, 'html/node' - autoload :Document, 'html/document' - autoload :FullSanitizer, 'html/sanitizer' - autoload :LinkSanitizer, 'html/sanitizer' - autoload :Node, 'html/node' - autoload :Sanitizer, 'html/sanitizer' - autoload :Selector, 'html/selector' - autoload :Tag, 'html/node' - autoload :Text, 'html/node' - autoload :Tokenizer, 'html/tokenizer' - autoload :Version, 'html/version' - autoload :WhiteListSanitizer, 'html/sanitizer' + eager_autoload do + autoload :CDATA, 'html/node' + autoload :Document, 'html/document' + autoload :FullSanitizer, 'html/sanitizer' + autoload :LinkSanitizer, 'html/sanitizer' + autoload :Node, 'html/node' + autoload :Sanitizer, 'html/sanitizer' + autoload :Selector, 'html/selector' + autoload :Tag, 'html/node' + autoload :Text, 'html/node' + autoload :Tokenizer, 'html/tokenizer' + autoload :Version, 'html/version' + autoload :WhiteListSanitizer, 'html/sanitizer' + end end diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb index 48b5652a89..fafcf7dc4e 100644 --- a/actionpack/lib/action_dispatch.rb +++ b/actionpack/lib/action_dispatch.rb @@ -37,43 +37,38 @@ module ActionDispatch autoload_under 'http' do autoload :Request autoload :Response - autoload :StatusCodes end - deferrable do - autoload_under 'middleware' do - autoload :Callbacks - autoload :ParamsParser - autoload :Rescue - autoload :ShowExceptions - autoload :Static - autoload :StringCoercion - end - - autoload :MiddlewareStack, 'action_dispatch/middleware/stack' - autoload :Routing + autoload_under 'middleware' do + autoload :Callbacks + autoload :ParamsParser + autoload :Rescue + autoload :ShowExceptions + autoload :Static + autoload :StringCoercion + end - module Http - autoload :Headers, 'action_dispatch/http/headers' - end + autoload :MiddlewareStack, 'action_dispatch/middleware/stack' + autoload :Routing - module Session - autoload :AbstractStore, 'action_dispatch/middleware/session/abstract_store' - autoload :CookieStore, 'action_dispatch/middleware/session/cookie_store' - autoload :MemCacheStore, 'action_dispatch/middleware/session/mem_cache_store' - end + module Http + autoload :Headers, 'action_dispatch/http/headers' + end - autoload_under 'testing' do - autoload :Assertions - autoload :Integration - autoload :PerformanceTest - autoload :TestProcess - autoload :TestRequest - autoload :TestResponse - end + module Session + autoload :AbstractStore, 'action_dispatch/middleware/session/abstract_store' + autoload :CookieStore, 'action_dispatch/middleware/session/cookie_store' + autoload :MemCacheStore, 'action_dispatch/middleware/session/mem_cache_store' end - autoload :HTML, 'action_controller/vendor/html-scanner' + autoload_under 'testing' do + autoload :Assertions + autoload :Integration + autoload :PerformanceTest + autoload :TestProcess + autoload :TestRequest + autoload :TestResponse + end end autoload :Mime, 'action_dispatch/http/mime_type' diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index bc17cadb38..6e8a5dcb8a 100755 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -18,7 +18,7 @@ module ActionDispatch HTTP_ACCEPT HTTP_ACCEPT_CHARSET HTTP_ACCEPT_ENCODING HTTP_ACCEPT_LANGUAGE HTTP_CACHE_CONTROL HTTP_FROM - HTTP_NEGOTIATE HTTP_PRAGMA HTTP_REFERER HTTP_USER_AGENT ].each do |env| + HTTP_NEGOTIATE HTTP_PRAGMA ].each do |env| define_method(env.sub(/^HTTP_/n, '').downcase) do @env[env] end diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index 6dc563264f..8524bbd993 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -60,7 +60,7 @@ module ActionDispatch # :nodoc: end def status=(status) - @status = ActionDispatch::StatusCodes[status] + @status = Rack::Utils.status_code(status) end # The response code of the request @@ -74,7 +74,7 @@ module ActionDispatch # :nodoc: end def message - StatusCodes::STATUS_CODES[@status] + Rack::Utils::HTTP_STATUS_CODES[@status] end alias_method :status_message, :message diff --git a/actionpack/lib/action_dispatch/http/status_codes.rb b/actionpack/lib/action_dispatch/http/status_codes.rb deleted file mode 100644 index 3d6ee685ea..0000000000 --- a/actionpack/lib/action_dispatch/http/status_codes.rb +++ /dev/null @@ -1,33 +0,0 @@ -require 'active_support/inflector' - -module ActionDispatch - module StatusCodes #:nodoc: - STATUS_CODES = Rack::Utils::HTTP_STATUS_CODES.merge({ - 102 => "Processing", - 207 => "Multi-Status", - 226 => "IM Used", - 422 => "Unprocessable Entity", - 423 => "Locked", - 424 => "Failed Dependency", - 426 => "Upgrade Required", - 507 => "Insufficient Storage", - 510 => "Not Extended" - }).freeze - - def self.[](status) - if status.is_a?(Symbol) - SYMBOL_TO_STATUS_CODE[status] || 500 - else - status.to_i - end - end - - # Provides a symbol-to-fixnum lookup for converting a symbol (like - # :created or :not_implemented) into its corresponding HTTP status - # code (like 200 or 501). - SYMBOL_TO_STATUS_CODE = STATUS_CODES.inject({}) { |hash, (code, message)| - hash[ActiveSupport::Inflector.underscore(message.gsub(/ /, "")).to_sym] = code - hash - }.freeze - end -end diff --git a/actionpack/lib/action_dispatch/middleware/params_parser.rb b/actionpack/lib/action_dispatch/middleware/params_parser.rb index 8970ccaf07..534390d4aa 100644 --- a/actionpack/lib/action_dispatch/middleware/params_parser.rb +++ b/actionpack/lib/action_dispatch/middleware/params_parser.rb @@ -1,4 +1,5 @@ require 'active_support/json' +require 'action_dispatch/http/request' module ActionDispatch class ParamsParser diff --git a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb index c5c06f74a2..7d4f0998ce 100644 --- a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb +++ b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb @@ -1,4 +1,5 @@ require 'rack/utils' +require 'rack/request' module ActionDispatch module Session diff --git a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb index bd552b458a..f27f22c7e7 100644 --- a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb +++ b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb @@ -1,4 +1,5 @@ -require "active_support/core_ext/hash/keys" +require 'active_support/core_ext/hash/keys' +require 'rack/request' module ActionDispatch module Session @@ -49,7 +50,7 @@ module ActionDispatch :expire_after => nil, :httponly => true }.freeze - + class OptionsHash < Hash def initialize(by, env, default_options) @session_data = env[CookieStore::ENV_SESSION_KEY] @@ -60,7 +61,7 @@ module ActionDispatch key == :id ? @session_data[:session_id] : super(key) end end - + ENV_SESSION_KEY = "rack.session".freeze ENV_SESSION_OPTIONS_KEY = "rack.session.options".freeze HTTP_SET_COOKIE = "Set-Cookie".freeze @@ -102,7 +103,7 @@ module ActionDispatch def call(env) env[ENV_SESSION_KEY] = AbstractStore::SessionHash.new(self, env) env[ENV_SESSION_OPTIONS_KEY] = OptionsHash.new(self, env, @default_options) - + status, headers, body = @app.call(env) session_data = env[ENV_SESSION_KEY] diff --git a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb index bd87764f5b..4ebc8a2ab9 100644 --- a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb @@ -1,4 +1,5 @@ -require "active_support/core_ext/exception" +require 'active_support/core_ext/exception' +require 'action_dispatch/http/request' module ActionDispatch class ShowExceptions @@ -101,7 +102,7 @@ module ActionDispatch end def status_code(exception) - ActionDispatch::StatusCodes::SYMBOL_TO_STATUS_CODE[@@rescue_responses[exception.class.name]] + Rack::Utils.status_code(@@rescue_responses[exception.class.name]) end def render(status, body) diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 46163706c3..a6b32e0152 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -19,9 +19,9 @@ module ActionDispatch @constraints.each { |constraint| if constraint.respond_to?(:matches?) && !constraint.matches?(req) - return [417, {}, []] + return [ 417, {}, [] ] elsif constraint.respond_to?(:call) && !constraint.call(req) - return [417, {}, []] + return [ 417, {}, [] ] end } @@ -29,94 +29,138 @@ module ActionDispatch end end - module Base - def initialize(set) - @set = set + class Mapping + def initialize(set, scope, args) + @set, @scope = set, scope + @path, @options = extract_path_and_options(args) end - - def root(options = {}) - match '/', options.merge(:as => :root) + + def to_route + [ app, conditions, requirements, defaults, @options[:as] ] end - - def match(*args) - if args.one? && args.first.is_a?(Hash) - path = args.first.keys.first - options = { :to => args.first.values.first } - else - path = args.first + + private + def extract_path_and_options(args) options = args.extract_options! - end - - conditions, defaults = {}, {} - - path = nil if path == "" - path = "#{@scope[:path]}#{path}" if @scope[:path] - path = Rack::Mount::Utils.normalize_path(path) if path - - raise ArgumentError, "path is required" unless path - constraints = options[:constraints] || {} - unless constraints.is_a?(Hash) - block, constraints = constraints, {} + if args.empty? + path, to = options.find { |name, value| name.is_a?(String) } + options.merge!(:to => to).delete(path) if path + else + path = args.first + end + + [ normalize_path(path), options ] end - blocks = ((@scope[:blocks] || []) + [block]).compact - constraints = (@scope[:constraints] || {}).merge(constraints) - options.each { |k, v| constraints[k] = v if v.is_a?(Regexp) } - conditions[:path_info] = path - requirements = constraints.dup + def normalize_path(path) + path = nil if path == "" + path = "#{@scope[:path]}#{path}" if @scope[:path] + path = Rack::Mount::Utils.normalize_path(path) if path - path_regexp = Rack::Mount::Strexp.compile(path, constraints, SEPARATORS) - segment_keys = Rack::Mount::RegexpWithNamedGroups.new(path_regexp).names - constraints.reject! { |k, v| segment_keys.include?(k.to_s) } - conditions.merge!(constraints) + raise ArgumentError, "path is required" unless path + + path + end - requirements[:controller] ||= @set.controller_constraints - if via = options[:via] - via = Array(via).map { |m| m.to_s.upcase } - conditions[:request_method] = Regexp.union(*via) + def app + Constraints.new( + to.respond_to?(:call) ? to : Routing::RouteSet::Dispatcher.new(:defaults => defaults), + blocks + ) end - defaults[:controller] ||= @scope[:controller].to_s if @scope[:controller] - - app = initialize_app_endpoint(options, defaults) - validate_defaults!(app, defaults, segment_keys) - app = Constraints.new(app, blocks) + def conditions + { :path_info => @path }.merge(constraints).merge(request_method_condition) + end + + def requirements + @requirements ||= returning(@options[:constraints] || {}) do |requirements| + requirements.reverse_merge!(@scope[:constraints]) if @scope[:constraints] + @options.each { |k, v| requirements[k] = v if v.is_a?(Regexp) } + requirements[:controller] ||= @set.controller_constraints + end + end - @set.add_route(app, conditions, requirements, defaults, options[:as]) + def defaults + @defaults ||= if to.respond_to?(:call) + { } + else + defaults = case to + when String + controller, action = to.split('#') + { :controller => controller, :action => action } + when Symbol + { :controller => default_controller, :action => to.to_s } + else + { :controller => default_controller } + end + + if defaults[:controller].blank? && segment_keys.exclude?("controller") + raise ArgumentError, "missing :controller" + end + + if defaults[:action].blank? && segment_keys.exclude?("action") + raise ArgumentError, "missing :action" + end + + defaults + end + end - self - end + + def blocks + if @options[:constraints].present? && !@options[:constraints].is_a?(Hash) + block = @options[:constraints] + else + block = nil + end + + ((@scope[:blocks] || []) + [ block ]).compact + end + + def constraints + @constraints ||= requirements.reject { |k, v| segment_keys.include?(k.to_s) || k == :controller } + end - private - def initialize_app_endpoint(options, defaults) - app = nil - - if options[:to].respond_to?(:call) - app = options[:to] - defaults.delete(:controller) - defaults.delete(:action) - elsif options[:to].is_a?(String) - defaults[:controller], defaults[:action] = options[:to].split('#') - elsif options[:to].is_a?(Symbol) - defaults[:action] = options[:to].to_s + def request_method_condition + if via = @options[:via] + via = Array(via).map { |m| m.to_s.upcase } + { :request_method => Regexp.union(*via) } + else + { } end + end + + def segment_keys + @segment_keys ||= Rack::Mount::RegexpWithNamedGroups.new( + Rack::Mount::Strexp.compile(@path, requirements, SEPARATORS) + ).names + end - app || Routing::RouteSet::Dispatcher.new(:defaults => defaults) + def to + @options[:to] + end + + def default_controller + @scope[:controller].to_s if @scope[:controller] end + end - def validate_defaults!(app, defaults, segment_keys) - return unless app.is_a?(Routing::RouteSet::Dispatcher) + module Base + def initialize(set) + @set = set + end - unless defaults.include?(:controller) || segment_keys.include?("controller") - raise ArgumentError, "missing :controller" - end + def root(options = {}) + match '/', options.reverse_merge(:as => :root) + end - unless defaults.include?(:action) || segment_keys.include?("action") - raise ArgumentError, "missing :action" - end - end + def match(*args) + @set.add_route(*Mapping.new(@set, @scope, args).to_route) + self + end end module HttpHelpers @@ -139,15 +183,16 @@ module ActionDispatch def redirect(*args, &block) options = args.last.is_a?(Hash) ? args.pop : {} - path = args.shift || block - path_proc = path.is_a?(Proc) ? path : proc {|params| path % params } - status = options[:status] || 301 + path = args.shift || block + path_proc = path.is_a?(Proc) ? path : proc { |params| path % params } + status = options[:status] || 301 lambda do |env| - req = Rack::Request.new(env) + req = Rack::Request.new(env) params = path_proc.call(env["action_dispatch.request.path_parameters"]) - url = req.scheme + '://' + req.host + params - [status, {'Location' => url, 'Content-Type' => 'text/html'}, ['Moved Permanently']] + url = req.scheme + '://' + req.host + params + + [ status, {'Location' => url, 'Content-Type' => 'text/html'}, ['Moved Permanently'] ] end end @@ -211,11 +256,11 @@ module ActionDispatch self ensure - @scope[:path] = path if path_set + @scope[:path] = path if path_set @scope[:name_prefix] = name_prefix if name_prefix_set - @scope[:controller] = controller if controller_set - @scope[:options] = options - @scope[:blocks] = blocks + @scope[:controller] = controller if controller_set + @scope[:options] = options + @scope[:blocks] = blocks @scope[:constraints] = constraints end @@ -311,12 +356,12 @@ module ActionDispatch with_scope_level(:resource, resource) do yield if block_given? - get "(.:format)", :to => :show, :as => resource.member_name - post "(.:format)", :to => :create - put "(.:format)", :to => :update - delete "(.:format)", :to => :destroy - get "/new(.:format)", :to => :new, :as => "new_#{resource.singular}" - get "/edit(.:format)", :to => :edit, :as => "edit_#{resource.singular}" + get "(.:format)", :to => :show, :as => resource.member_name + post "(.:format)", :to => :create + put "(.:format)", :to => :update + delete "(.:format)", :to => :destroy + get "/new(.:format)", :to => :new, :as => "new_#{resource.singular}" + get "/edit(.:format)", :to => :edit, :as => "edit_#{resource.singular}" end end @@ -346,8 +391,9 @@ module ActionDispatch yield if block_given? with_scope_level(:collection) do - get "(.:format)", :to => :index, :as => resource.collection_name + get "(.:format)", :to => :index, :as => resource.collection_name post "(.:format)", :to => :create + with_exclusive_name_prefix :new do get "/new(.:format)", :to => :new, :as => resource.singular end @@ -355,9 +401,10 @@ module ActionDispatch with_scope_level(:member) do scope("/:id") do - get "(.:format)", :to => :show, :as => resource.member_name - put "(.:format)", :to => :update + get "(.:format)", :to => :show, :as => resource.member_name + put "(.:format)", :to => :update delete "(.:format)", :to => :destroy + with_exclusive_name_prefix :edit do get "/edit(.:format)", :to => :edit, :as => resource.singular end @@ -473,4 +520,4 @@ module ActionDispatch include Resources end end -end +end
\ No newline at end of file diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index a4dc5e0956..498ad3268c 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -273,7 +273,7 @@ module ActionDispatch # TODO: Move this into Railties if defined?(Rails.application) # Find namespaces in controllers/ directory - Rails.application.configuration.controller_paths.each do |load_path| + Rails.application.config.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}\/?/, '') diff --git a/actionpack/lib/action_dispatch/testing/assertions/dom.rb b/actionpack/lib/action_dispatch/testing/assertions/dom.rb index 9a917f704a..9c215de743 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/dom.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/dom.rb @@ -1,3 +1,5 @@ +require 'action_controller/vendor/html-scanner' + module ActionDispatch module Assertions module DomAssertions @@ -15,7 +17,7 @@ module ActionDispatch assert_block(full_message) { expected_dom == actual_dom } end - + # The negated form of +assert_dom_equivalent+. # # ==== Examples diff --git a/actionpack/lib/action_dispatch/testing/assertions/response.rb b/actionpack/lib/action_dispatch/testing/assertions/response.rb index 501a7c4dfb..5686bbdbde 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/response.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/response.rb @@ -28,7 +28,7 @@ module ActionDispatch assert_block("") { true } # to count the assertion elsif type.is_a?(Fixnum) && @response.response_code == type assert_block("") { true } # to count the assertion - elsif type.is_a?(Symbol) && @response.response_code == ActionDispatch::StatusCodes::SYMBOL_TO_STATUS_CODE[type] + elsif type.is_a?(Symbol) && @response.response_code == Rack::Utils::SYMBOL_TO_STATUS_CODE[type] assert_block("") { true } # to count the assertion else assert_block(build_message(message, "Expected response to be a <?>, but was <?>", type, @response.response_code)) { false } diff --git a/actionpack/lib/action_dispatch/testing/assertions/selector.rb b/actionpack/lib/action_dispatch/testing/assertions/selector.rb index d22adfa749..c2dc591ff7 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/selector.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/selector.rb @@ -1,3 +1,5 @@ +require 'action_controller/vendor/html-scanner' + #-- # Copyright (c) 2006 Assaf Arkin (http://labnotes.org) # Under MIT and/or CC By license. @@ -16,7 +18,7 @@ module ActionDispatch # # Use +css_select+ to select elements without making an assertions, either # from the response HTML or elements selected by the enclosing assertion. - # + # # In addition to HTML responses, you can make the following assertions: # * +assert_select_rjs+ - Assertions on HTML content of RJS update and insertion operations. # * +assert_select_encoded+ - Assertions on HTML encoded inside XML, for example for dealing with feed item descriptions. @@ -53,8 +55,8 @@ module ActionDispatch # end # # # Selects all list items in unordered lists - # items = css_select("ul>li") - # + # items = css_select("ul>li") + # # # Selects all form tags and then all inputs inside the form # forms = css_select("form") # forms.each do |form| @@ -212,7 +214,7 @@ module ActionDispatch # Otherwise just operate on the response document. root = response_from_page_or_rjs end - + # First or second argument is the selector: string and we pass # all remaining arguments. Array and we pass the argument. Also # accepts selector itself. @@ -225,7 +227,7 @@ module ActionDispatch selector = arg else raise ArgumentError, "Expecting a selector as the first argument" end - + # Next argument is used for equality tests. equals = {} case arg = args.shift @@ -315,10 +317,10 @@ module ActionDispatch # Returns all matches elements. matches end - + def count_description(min, max) #:nodoc: pluralize = lambda {|word, quantity| word << (quantity == 1 ? '' : 's')} - + if min && max && (max != min) "between #{min} and #{max} elements" elsif min && !(min == 1 && max == 1) @@ -327,7 +329,7 @@ module ActionDispatch "at most #{max} #{pluralize['element', max]}" end end - + # :call-seq: # assert_select_rjs(id?) { |elements| ... } # assert_select_rjs(statement, id?) { |elements| ... } @@ -344,7 +346,7 @@ module ActionDispatch # that update or insert an element with that identifier. # # Use the first argument to narrow down assertions to only statements - # of that type. Possible values are <tt>:replace</tt>, <tt>:replace_html</tt>, + # of that type. Possible values are <tt>:replace</tt>, <tt>:replace_html</tt>, # <tt>:show</tt>, <tt>:hide</tt>, <tt>:toggle</tt>, <tt>:remove</tta>, # <tt>:insert_html</tt> and <tt>:redirect</tt>. # @@ -494,7 +496,7 @@ module ActionDispatch # end # end # end - # + # # # # Selects all paragraph tags from within the description of an RSS feed # assert_select_feed :rss, 2.0 do diff --git a/actionpack/lib/action_dispatch/testing/assertions/tag.rb b/actionpack/lib/action_dispatch/testing/assertions/tag.rb index b74dcb1fe4..5c735e61b2 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/tag.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/tag.rb @@ -1,3 +1,5 @@ +require 'action_controller/vendor/html-scanner' + module ActionDispatch module Assertions # Pair of assertions to testing elements in the HTML output of the response. diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index 5c127dfe37..2a5f5dcd5c 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -411,7 +411,7 @@ module ActionDispatch # At its simplest, you simply extend IntegrationTest and write your tests # using the get/post methods: # - # require "#{File.dirname(__FILE__)}/test_helper" + # require "test_helper" # # class ExampleTest < ActionController::IntegrationTest # fixtures :people @@ -435,7 +435,7 @@ module ActionDispatch # powerful testing DSL that is specific for your application. You can even # reference any named routes you happen to have defined! # - # require "#{File.dirname(__FILE__)}/test_helper" + # require "test_helper" # # class AdvancedTest < ActionController::IntegrationTest # fixtures :people, :rooms diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb index aabe8c4314..8ce6e82524 100644 --- a/actionpack/lib/action_view.rb +++ b/actionpack/lib/action_view.rb @@ -31,29 +31,30 @@ require 'action_pack' module ActionView extend ActiveSupport::Autoload - autoload :Base - autoload :Context - autoload :Template - autoload :Helpers - autoload :SafeBuffer - - - autoload_under "render" do - autoload :Partials - autoload :Rendering + eager_autoload do + autoload :Context + autoload :Template + autoload :Helpers + autoload :SafeBuffer + + autoload_under "render" do + autoload :Partials + autoload :Rendering + end + + autoload :MissingTemplate, 'action_view/base' + autoload :Resolver, 'action_view/template/resolver' + autoload :PathResolver, 'action_view/template/resolver' + autoload :PathSet, 'action_view/paths' + autoload :FileSystemResolverWithFallback, 'action_view/template/resolver' + + autoload :TemplateError, 'action_view/template/error' + autoload :TemplateHandler, 'action_view/template' + autoload :TemplateHandlers, 'action_view/template' end - - autoload :MissingTemplate, 'action_view/base' - autoload :Resolver, 'action_view/template/resolver' - autoload :PathResolver, 'action_view/template/resolver' - autoload :PathSet, 'action_view/paths' - autoload :FileSystemResolverWithFallback, 'action_view/template/resolver' - - autoload :TemplateError, 'action_view/template/error' - autoload :TemplateHandler, 'action_view/template' - autoload :TemplateHandlers, 'action_view/template' end require 'action_view/erb/util' +require 'action_view/base' I18n.load_path << "#{File.dirname(__FILE__)}/action_view/locale/en.yml" diff --git a/actionpack/lib/action_view/helpers/sanitize_helper.rb b/actionpack/lib/action_view/helpers/sanitize_helper.rb index 69d0d0fb67..f03ffe5ef4 100644 --- a/actionpack/lib/action_view/helpers/sanitize_helper.rb +++ b/actionpack/lib/action_view/helpers/sanitize_helper.rb @@ -1,3 +1,4 @@ +require 'action_controller/vendor/html-scanner' require 'action_view/helpers/tag_helper' module ActionView diff --git a/actionpack/lib/action_view/helpers/translation_helper.rb b/actionpack/lib/action_view/helpers/translation_helper.rb index 564f12c955..35c431d78d 100644 --- a/actionpack/lib/action_view/helpers/translation_helper.rb +++ b/actionpack/lib/action_view/helpers/translation_helper.rb @@ -12,7 +12,7 @@ module ActionView # prepend the key with a period, nothing is converted. def translate(key, options = {}) options[:raise] = true - I18n.translate(scope_key_by_partial(key), options) + I18n.translate(scope_key_by_partial(key), options).html_safe! rescue I18n::MissingTranslationData => e keys = I18n.send(:normalize_translation_keys, e.locale, e.key, e.options[:scope]) content_tag('span', keys.join(', '), :class => 'translation_missing') diff --git a/actionpack/lib/action_view/safe_buffer.rb b/actionpack/lib/action_view/safe_buffer.rb index 09f44ab26f..6be05b9e1e 100644 --- a/actionpack/lib/action_view/safe_buffer.rb +++ b/actionpack/lib/action_view/safe_buffer.rb @@ -1,4 +1,3 @@ - module ActionView #:nodoc: class SafeBuffer < String def <<(value) diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb index 210ad508f5..d46c989d11 100644 --- a/actionpack/lib/action_view/template.rb +++ b/actionpack/lib/action_view/template.rb @@ -7,12 +7,14 @@ require "action_view/template/resolver" module ActionView class Template extend ActiveSupport::Autoload - - autoload :Error - autoload :Handler - autoload :Handlers - autoload :Text - + + eager_autoload do + autoload :Error + autoload :Handler + autoload :Handlers + autoload :Text + end + extend Template::Handlers attr_reader :source, :identifier, :handler, :mime_type, :formats, :details @@ -114,21 +116,6 @@ module ActionView end end - class LocalsKey - @hash_keys = Hash.new {|h,k| h[k] = Hash.new {|h,k| h[k] = {} } } - - def self.get(*locals) - @hash_keys[*locals] ||= new(klass, format, locale) - end - - attr_accessor :hash - def initialize(klass, format, locale) - @hash = locals.hash - end - - alias_method :eql?, :equal? - end - def build_method_name(locals) # TODO: is locals.keys.hash reliably the same? @method_names[locals.keys.hash] ||= diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb index f8e6376589..93a4315108 100644 --- a/actionpack/lib/action_view/template/handlers/erb.rb +++ b/actionpack/lib/action_view/template/handlers/erb.rb @@ -10,7 +10,8 @@ module ActionView end def add_text(src, text) - src << "@output_buffer << ('" << escape_text(text) << "'.html_safe!);" + return if text.empty? + src << "@output_buffer.safe_concat('" << escape_text(text) << "');" end def add_expr_literal(src, code) diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index f26b15d2e0..54f2739d38 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -1125,7 +1125,7 @@ class RenderTest < ActionController::TestCase assert !@response.headers.include?('Content-Length') assert_response :no_content - ActionDispatch::StatusCodes::SYMBOL_TO_STATUS_CODE.each do |status, code| + Rack::Utils::SYMBOL_TO_STATUS_CODE.each do |status, code| get :head_with_symbolic_status, :status => status.to_s assert_equal code, @response.response_code assert_response status @@ -1133,7 +1133,7 @@ class RenderTest < ActionController::TestCase end def test_head_with_integer_status - ActionDispatch::StatusCodes::STATUS_CODES.each do |code, message| + Rack::Utils::HTTP_STATUS_CODES.each do |code, message| get :head_with_integer_status, :status => code.to_s assert_equal message, @response.message end diff --git a/actionpack/test/dispatch/response_test.rb b/actionpack/test/dispatch/response_test.rb index 59ad2e48bd..02f63f7006 100644 --- a/actionpack/test/dispatch/response_test.rb +++ b/actionpack/test/dispatch/response_test.rb @@ -178,7 +178,7 @@ class ResponseIntegrationTest < ActionDispatch::IntegrationTest @app = lambda { |env| [200, {'ETag' => '"202cb962ac59075b964b07152d234b70"', - 'Cache-Control' => 'public'}, 'Hello'] + 'Cache-Control' => 'public'}, ['Hello']] } get '/' @@ -217,7 +217,7 @@ class ResponseIntegrationTest < ActionDispatch::IntegrationTest @app = lambda { |env| [200, {'Content-Type' => 'application/xml; charset=utf-16'}, - 'Hello'] + ['Hello']] } get '/' diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index 1c7822358d..360ffe977b 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -22,7 +22,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest delete 'logout', :to => :destroy, :as => :logout end - match 'account/logout' => redirect("/logout") + match 'account/logout' => redirect("/logout"), :as => :logout_redirect match 'account/login', :to => redirect("/login") match 'account/modulo/:name', :to => redirect("/%{name}s") @@ -109,7 +109,9 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest scope ':access_token', :constraints => { :access_token => /\w{5,5}/ } do resources :rooms end - + + match '/info' => 'projects#info', :as => 'info' + root :to => 'projects#index' end end @@ -153,6 +155,7 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest def test_logout_redirect_without_to with_test_routes do + assert_equal '/account/logout', logout_redirect_path get '/account/logout' assert_equal 301, @response.status assert_equal 'http://www.example.com/logout', @response.headers['Location'] @@ -462,10 +465,27 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest def test_root with_test_routes do + assert_equal '/', root_path get '/' assert_equal 'projects#index', @response.body end end + + def test_index + with_test_routes do + assert_equal '/info', info_path + get '/info' + assert_equal 'projects#info', @response.body + end + end + + def test_index + with_test_routes do + assert_equal '/info', info_path + get '/info' + assert_equal 'projects#info', @response.body + end + end private def with_test_routes diff --git a/activemodel/lib/active_model/validations.rb b/activemodel/lib/active_model/validations.rb index 064ec98f3a..a0d64507f9 100644 --- a/activemodel/lib/active_model/validations.rb +++ b/activemodel/lib/active_model/validations.rb @@ -1,5 +1,6 @@ require 'active_support/core_ext/array/extract_options' require 'active_support/core_ext/hash/keys' +require 'active_model/errors' module ActiveModel module Validations diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb index 2376bbd04a..196b87c0ac 100644 --- a/activerecord/lib/active_record.rb +++ b/activerecord/lib/active_record.rb @@ -35,82 +35,94 @@ require 'arel' module ActiveRecord extend ActiveSupport::Autoload - autoload :VERSION - - autoload :ActiveRecordError, 'active_record/base' - autoload :ConnectionNotEstablished, 'active_record/base' - - autoload :Aggregations - autoload :AssociationPreload - autoload :Associations - autoload :AttributeMethods - autoload :Attributes - autoload :AutosaveAssociation - autoload :Relation - autoload :Base - autoload :Batches - autoload :Calculations - autoload :Callbacks - autoload :DynamicFinderMatch - autoload :DynamicScopeMatch - autoload :Migration - autoload :Migrator, 'active_record/migration' - autoload :NamedScope - autoload :NestedAttributes - autoload :Observer - autoload :QueryCache - autoload :Reflection - autoload :Schema - autoload :SchemaDumper - autoload :Serialization - autoload :SessionStore - autoload :StateMachine - autoload :Timestamp - autoload :Transactions - autoload :Types - autoload :Validations + eager_autoload do + autoload :VERSION + + autoload :ActiveRecordError, 'active_record/base' + autoload :ConnectionNotEstablished, 'active_record/base' + + autoload :Aggregations + autoload :AssociationPreload + autoload :Associations + autoload :AttributeMethods + autoload :Attributes + autoload :AutosaveAssociation + autoload :Relation + autoload :Base + autoload :Batches + autoload :Calculations + autoload :Callbacks + autoload :DynamicFinderMatch + autoload :DynamicScopeMatch + autoload :Migration + autoload :Migrator, 'active_record/migration' + autoload :NamedScope + autoload :NestedAttributes + autoload :Observer + autoload :QueryCache + autoload :Reflection + autoload :Schema + autoload :SchemaDumper + autoload :Serialization + autoload :SessionStore + autoload :StateMachine + autoload :Timestamp + autoload :Transactions + autoload :Types + autoload :Validations + end module AttributeMethods extend ActiveSupport::Autoload - autoload :BeforeTypeCast - autoload :Dirty - autoload :PrimaryKey - autoload :Query - autoload :Read - autoload :TimeZoneConversion - autoload :Write + eager_autoload do + autoload :BeforeTypeCast + autoload :Dirty + autoload :PrimaryKey + autoload :Query + autoload :Read + autoload :TimeZoneConversion + autoload :Write + end end module Attributes extend ActiveSupport::Autoload - autoload :Aliasing - autoload :Store - autoload :Typecasting + eager_autoload do + autoload :Aliasing + autoload :Store + autoload :Typecasting + end end module Type extend ActiveSupport::Autoload - autoload :Number, 'active_record/types/number' - autoload :Object, 'active_record/types/object' - autoload :Serialize, 'active_record/types/serialize' - autoload :TimeWithZone, 'active_record/types/time_with_zone' - autoload :Unknown, 'active_record/types/unknown' + eager_autoload do + autoload :Number, 'active_record/types/number' + autoload :Object, 'active_record/types/object' + autoload :Serialize, 'active_record/types/serialize' + autoload :TimeWithZone, 'active_record/types/time_with_zone' + autoload :Unknown, 'active_record/types/unknown' + end end module Locking extend ActiveSupport::Autoload - autoload :Optimistic - autoload :Pessimistic + eager_autoload do + autoload :Optimistic + autoload :Pessimistic + end end module ConnectionAdapters extend ActiveSupport::Autoload - autoload :AbstractAdapter + eager_autoload do + autoload :AbstractAdapter + end end end diff --git a/activerecord/lib/active_record/notifications.rb b/activerecord/lib/active_record/notifications.rb deleted file mode 100644 index 562a5b91f4..0000000000 --- a/activerecord/lib/active_record/notifications.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'active_support/notifications' - -ActiveSupport::Notifications.subscribe("sql") do |name, before, after, result, instrumenter_id, payload| - ActiveRecord::Base.connection.log_info(payload[:sql], name, after - before) -end diff --git a/activerecord/lib/active_record/rails.rb b/activerecord/lib/active_record/rails.rb new file mode 100644 index 0000000000..ddbc555113 --- /dev/null +++ b/activerecord/lib/active_record/rails.rb @@ -0,0 +1,59 @@ +# For now, action_controller must always be present with +# rails, so let's make sure that it gets required before +# here. This is needed for correctly setting up the middleware. +# In the future, this might become an optional require. +require "action_controller/rails" + +module ActiveRecord + class Plugin < Rails::Plugin + plugin_name :active_record + + initializer "active_record.set_configs" do |app| + app.config.active_record.each do |k,v| + ActiveRecord::Base.send "#{k}=", v + end + end + + # This sets the database configuration from Configuration#database_configuration + # and then establishes the connection. + initializer "active_record.initialize_database" do |app| + ActiveRecord::Base.configurations = app.config.database_configuration + ActiveRecord::Base.establish_connection + end + + initializer "active_record.initialize_timezone" do + ActiveRecord::Base.time_zone_aware_attributes = true + ActiveRecord::Base.default_timezone = :utc + end + + # Setup database middleware after initializers have run + initializer "active_record.initialize_database_middleware" do |app| + middleware = app.config.middleware + if middleware.include?(ActiveRecord::SessionStore) + middleware.insert_before ActiveRecord::SessionStore, ActiveRecord::ConnectionAdapters::ConnectionManagement + middleware.insert_before ActiveRecord::SessionStore, ActiveRecord::QueryCache + else + middleware.use ActiveRecord::ConnectionAdapters::ConnectionManagement + middleware.use ActiveRecord::QueryCache + end + end + + initializer "active_record.load_observers" do + ActiveRecord::Base.instantiate_observers + end + + # TODO: ActiveRecord::Base.logger should delegate to its own config.logger + initializer "active_record.logger" do + ActiveRecord::Base.logger ||= Rails.logger + end + + initializer "active_record.notifications" do + require 'active_support/notifications' + + ActiveSupport::Notifications.subscribe("sql") do |name, before, after, result, instrumenter_id, payload| + ActiveRecord::Base.connection.log_info(payload[:sql], name, after - before) + end + end + + end +end
\ No newline at end of file diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb index b833e9c8ce..a6243e7011 100644 --- a/activeresource/lib/active_resource/base.rb +++ b/activeresource/lib/active_resource/base.rb @@ -13,6 +13,9 @@ require 'set' require 'uri' require 'active_resource/exceptions' +require 'active_resource/connection' +require 'active_resource/formats' +require 'active_resource/schema' module ActiveResource # ActiveResource::Base is the main class for mapping RESTful resources as models in a Rails application. diff --git a/activeresource/test/cases/base/schema_test.rb b/activeresource/test/cases/base/schema_test.rb index d1afb9f439..d9dc679941 100644 --- a/activeresource/test/cases/base/schema_test.rb +++ b/activeresource/test/cases/base/schema_test.rb @@ -1,4 +1,5 @@ require 'abstract_unit' +require 'active_support/core_ext/hash/conversions' require "fixtures/person" require "fixtures/street_address" diff --git a/activesupport/lib/active_support.rb b/activesupport/lib/active_support.rb index 9e21b3faf3..f2baa5a56a 100644 --- a/activesupport/lib/active_support.rb +++ b/activesupport/lib/active_support.rb @@ -39,31 +39,34 @@ require "active_support/dependencies/autoload" module ActiveSupport extend ActiveSupport::Autoload - autoload :BacktraceCleaner - autoload :Base64 - autoload :BasicObject - autoload :Benchmarkable - autoload :BufferedLogger - autoload :Cache - autoload :Callbacks - autoload :Concern - autoload :Configurable - autoload :DeprecatedCallbacks - autoload :Deprecation - autoload :Gzip - autoload :Inflector - autoload :Memoizable - autoload :MessageEncryptor - autoload :MessageVerifier - autoload :Multibyte - autoload :OptionMerger - autoload :OrderedHash - autoload :OrderedOptions - autoload :Notifications - autoload :Rescuable - autoload :SecureRandom - autoload :StringInquirer - autoload :XmlMini + # TODO: Narrow this list down + eager_autoload do + autoload :BacktraceCleaner + autoload :Base64 + autoload :BasicObject + autoload :Benchmarkable + autoload :BufferedLogger + autoload :Cache + autoload :Callbacks + autoload :Concern + autoload :Configurable + autoload :DeprecatedCallbacks + autoload :Deprecation + autoload :Gzip + autoload :Inflector + autoload :Memoizable + autoload :MessageEncryptor + autoload :MessageVerifier + autoload :Multibyte + autoload :OptionMerger + autoload :OrderedHash + autoload :OrderedOptions + autoload :Notifications + autoload :Rescuable + autoload :SecureRandom + autoload :StringInquirer + autoload :XmlMini + end end require 'active_support/vendor' diff --git a/activesupport/lib/active_support/core_ext/string/output_safety.rb b/activesupport/lib/active_support/core_ext/string/output_safety.rb index a2a88eb7df..3e6ab0ebd2 100644 --- a/activesupport/lib/active_support/core_ext/string/output_safety.rb +++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb @@ -1,7 +1,6 @@ class String - def html_safe? - defined?(@_rails_html_safe) && @_rails_html_safe - end + attr_accessor :_rails_html_safe + alias html_safe? _rails_html_safe def html_safe! @_rails_html_safe = true @@ -15,30 +14,16 @@ class String alias original_plus + def +(other) result = original_plus(other) - if html_safe? && also_html_safe?(other) - result.html_safe! - else - result - end + result._rails_html_safe = html_safe? && other.html_safe? + result end alias original_concat << + alias safe_concat << def <<(other) + @_rails_html_safe = false unless other.html_safe? result = original_concat(other) - unless html_safe? && also_html_safe?(other) - @_rails_html_safe = false - end - result end - remove_method :concat - def concat(other) - self << other - end - - private - def also_html_safe?(other) - other.respond_to?(:html_safe?) && other.html_safe? - end - + alias concat << end
\ No newline at end of file diff --git a/activesupport/lib/active_support/dependencies/autoload.rb b/activesupport/lib/active_support/dependencies/autoload.rb index 96ab04c61a..44edb89ad5 100644 --- a/activesupport/lib/active_support/dependencies/autoload.rb +++ b/activesupport/lib/active_support/dependencies/autoload.rb @@ -5,13 +5,13 @@ module ActiveSupport @@autoloads = {} @@under_path = nil @@at_path = nil - @@autoload_defer = false + @@eager_autoload = false def autoload(const_name, path = @@at_path) full = [self.name, @@under_path, const_name.to_s, path].compact.join("::") location = path || Inflector.underscore(full) - unless @@autoload_defer + if @@eager_autoload @@autoloads[const_name] = location end super const_name, location @@ -31,11 +31,11 @@ module ActiveSupport @@at_path = old_path end - def deferrable - old_defer, @@autoload_defer = @@autoload_defer, true + def eager_autoload + old_eager, @@eager_autoload = @@eager_autoload, true yield ensure - @@autoload_defer = old_defer + @@eager_autoload = old_eager end def self.eager_autoload! diff --git a/activesupport/lib/active_support/json/encoding.rb b/activesupport/lib/active_support/json/encoding.rb index 3c15056c41..c8415d5449 100644 --- a/activesupport/lib/active_support/json/encoding.rb +++ b/activesupport/lib/active_support/json/encoding.rb @@ -65,6 +65,15 @@ module ActiveSupport ESCAPED_CHARS = { + "\x00" => '\u0000', "\x01" => '\u0001', "\x02" => '\u0002', + "\x03" => '\u0003', "\x04" => '\u0004', "\x05" => '\u0005', + "\x06" => '\u0006', "\x07" => '\u0007', "\x0B" => '\u000B', + "\x0E" => '\u000E', "\x0F" => '\u000F', "\x10" => '\u0010', + "\x11" => '\u0011', "\x12" => '\u0012', "\x13" => '\u0013', + "\x14" => '\u0014', "\x15" => '\u0015', "\x16" => '\u0016', + "\x17" => '\u0017', "\x18" => '\u0018', "\x19" => '\u0019', + "\x1A" => '\u001A', "\x1B" => '\u001B', "\x1C" => '\u001C', + "\x1D" => '\u001D', "\x1E" => '\u001E', "\x1F" => '\u001F', "\010" => '\b', "\f" => '\f', "\n" => '\n', @@ -86,9 +95,9 @@ module ActiveSupport def escape_html_entities_in_json=(value) self.escape_regex = \ if @escape_html_entities_in_json = value - /[\010\f\n\r\t"\\><&]/ + /[\x00-\x1F"\\><&]/ else - /[\010\f\n\r\t"\\]/ + /[\x00-\x1F"\\]/ end end diff --git a/activesupport/lib/active_support/whiny_nil.rb b/activesupport/lib/active_support/whiny_nil.rb index c3ed659d6b..4f6ff7d3b5 100644 --- a/activesupport/lib/active_support/whiny_nil.rb +++ b/activesupport/lib/active_support/whiny_nil.rb @@ -43,10 +43,7 @@ class NilClass private def method_missing(method, *args, &block) - # Ruby 1.9.2: disallow explicit coercion via method_missing. - if method == :to_ary || method == :to_str - raise NoMethodError, "undefined method `#{method}' for nil:NilClass" - elsif klass = METHOD_CLASS_MAP[method] + if klass = METHOD_CLASS_MAP[method] raise_nil_warning_for klass, method, caller else super diff --git a/activesupport/test/json/encoding_test.rb b/activesupport/test/json/encoding_test.rb index 5d81d09f03..cf9a635b5f 100644 --- a/activesupport/test/json/encoding_test.rb +++ b/activesupport/test/json/encoding_test.rb @@ -23,7 +23,9 @@ class TestJSONEncoding < Test::Unit::TestCase StringTests = [[ 'this is the <string>', %("this is the \\u003Cstring\\u003E")], [ 'a "string" with quotes & an ampersand', %("a \\"string\\" with quotes \\u0026 an ampersand") ], - [ 'http://test.host/posts/1', %("http://test.host/posts/1")]] + [ 'http://test.host/posts/1', %("http://test.host/posts/1")], + [ "Control characters: \x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + %("Control characters: \\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000B\\f\\r\\u000E\\u000F\\u0010\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001A\\u001B\\u001C\\u001D\\u001E\\u001F") ]] ArrayTests = [[ ['a', 'b', 'c'], %([\"a\",\"b\",\"c\"]) ], [ [1, 'a', :b, nil, false], %([1,\"a\",\"b\",null,false]) ]] diff --git a/railties/builtin/routes.rb b/railties/builtin/routes.rb index 26a0daaa8c..ef9d9e756d 100644 --- a/railties/builtin/routes.rb +++ b/railties/builtin/routes.rb @@ -1,3 +1,3 @@ ActionController::Routing::Routes.draw do |map| - match '/rails/info/properties' => "rails::info#properties" + match '/rails/info/properties' => "rails/info#properties" end
\ No newline at end of file diff --git a/railties/lib/rails.rb b/railties/lib/rails.rb index 85aeb4af24..9fb3cd9f94 100644 --- a/railties/lib/rails.rb +++ b/railties/lib/rails.rb @@ -1,33 +1,9 @@ -require "pathname" - -require 'active_support' -require 'active_support/core_ext/kernel/reporting' -require 'active_support/core_ext/logger' -require 'action_dispatch' - -require 'rails/initializable' -require 'rails/application' -require 'rails/plugin' -require 'rails/railties_path' -require 'rails/version' -require 'rails/rack' -require 'rails/paths' -require 'rails/core' -require 'rails/configuration' -require 'rails/deprecation' -require 'rails/initializer' -require 'rails/ruby_version_check' - -# For Ruby 1.8, this initialization sets $KCODE to 'u' to enable the -# multibyte safe operations. Plugin authors supporting other encodings -# should override this behaviour and set the relevant +default_charset+ -# on ActionController::Base. -# -# For Ruby 1.9, UTF-8 is the default internal and external encoding. -if RUBY_VERSION < '1.9' - $KCODE='u' -else - Encoding.default_external = Encoding::UTF_8 -end - -RAILS_ENV = (ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development").dup unless defined?(RAILS_ENV) +require "rails/core" + +%w(active_model active_record action_controller action_view action_mailer active_resource).each do |framework| + begin + require framework + require "#{framework}/rails" + rescue LoadError + end +end
\ No newline at end of file diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index e6f2d30429..cd579a1c0d 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -1,91 +1,47 @@ +require "fileutils" +require 'active_support/core_ext/module/delegation' + module Rails class Application include Initializable class << self - # Stub out App initialize - def initialize! - new - end + attr_writer :config + alias configure class_eval + delegate :initialize!, :load_tasks, :to => :instance - def new - @instance ||= begin - begin - require config.environment_path - rescue LoadError - end - super - end + private :new + def instance + @instance ||= new end def config - @config ||= begin - config = Configuration.new - Plugin.plugins.each { |p| config.merge(p.config) } - config - end - end - - # TODO: change the plugin loader to use config - alias configuration config - - def config=(config) - @config = config - end - - def root - config.root - end - - def load_tasks - require "rails/tasks" - Dir["#{root}/vendor/plugins/*/**/tasks/**/*.rake"].sort.each { |ext| load ext } - Dir["#{root}/lib/tasks/**/*.rake"].sort.each { |ext| load ext } - task :environment do - $rails_rake_task = true - initialize! - end + @config ||= Configuration.new(Plugin::Configuration.default) end def routes ActionController::Routing::Routes end - - def call(env) - new.call(env) - end end + delegate :config, :routes, :to => :'self.class' + delegate :root, :middleware, :to => :config attr_reader :route_configuration_files def initialize + require_environment Rails.application ||= self - @route_configuration_files = [] - - run_initializers(self) - end - - def config - self.class.config end - class << self - alias configure class_eval - end - - def root - config.root - end - - alias configuration config - - def middleware - config.middleware + def initialize! + run_initializers(self) + self end - def routes - ActionController::Routing::Routes + def require_environment + require config.environment_path + rescue LoadError end def routes_changed_at @@ -114,16 +70,27 @@ module Rails routes.disable_clear_and_finalize = false end + def load_tasks + require "rails/tasks" + Dir["#{root}/vendor/plugins/*/**/tasks/**/*.rake"].sort.each { |ext| load ext } + Dir["#{root}/lib/tasks/**/*.rake"].sort.each { |ext| load ext } + task :environment do + $rails_rake_task = true + initialize! + end + end + def initializers initializers = super plugins.each { |p| initializers += p.initializers } initializers end + # TODO: Fix this method def plugins @plugins ||= begin plugin_names = config.plugins || [:all] - Plugin.plugins.select { |p| plugin_names.include?(p.plugin_name) } + + Plugin.plugins.select { |p| plugin_names.include?(:all) || plugin_names.include?(p.plugin_name) } + Plugin::Vendored.all(config.plugins || [:all], config.paths.vendor.plugins) end end @@ -133,6 +100,10 @@ module Rails @app.call(env) end + initializer :load_all_active_support do + require "active_support/all" unless config.active_support.bare + end + # Set the <tt>$LOAD_PATH</tt> based on the value of # Configuration#load_paths. Duplicates are removed. initializer :set_load_path do @@ -140,14 +111,6 @@ module Rails $LOAD_PATH.uniq! end - # Requires all frameworks specified by the Configuration#frameworks - # list. By default, all frameworks (Active Record, Active Support, - # Action Pack, Action Mailer, and Active Resource) are loaded. - initializer :require_frameworks do - require 'active_support/all' unless config.active_support.bare - config.frameworks.each { |framework| require(framework.to_s) } - end - # Set the paths from which Rails will automatically load source files, and # the load_once paths. initializer :set_autoload_paths do @@ -170,7 +133,7 @@ module Rails # Create tmp directories initializer :ensure_tmp_directories_exist do %w(cache pids sessions sockets).each do |dir_to_make| - FileUtils.mkdir_p(File.join(config.root, 'tmp', dir_to_make)) + FileUtils.mkdir_p(File.join(root, 'tmp', dir_to_make)) end end @@ -178,44 +141,7 @@ module Rails # Used by Passenger to ensure everything's loaded before forking and # to avoid autoload race conditions in JRuby. initializer :preload_frameworks do - if config.preload_frameworks - config.frameworks.each do |framework| - # String#classify and #constantize aren't available yet. - toplevel = Object.const_get(framework.to_s.gsub(/(?:^|_)(.)/) { $1.upcase }) - toplevel.load_all! if toplevel.respond_to?(:load_all!) - end - end - end - - # This initialization routine does nothing unless <tt>:active_record</tt> - # is one of the frameworks to load (Configuration#frameworks). If it is, - # this sets the database configuration from Configuration#database_configuration - # and then establishes the connection. - initializer :initialize_database do - if config.frameworks.include?(:active_record) - ActiveRecord::Base.configurations = config.database_configuration - ActiveRecord::Base.establish_connection - end - end - - # Include middleware to serve up static assets - initializer :initialize_static_server do - if config.frameworks.include?(:action_controller) && config.serve_static_assets - config.middleware.use(ActionDispatch::Static, Rails.public_path) - end - end - - initializer :initialize_middleware_stack do - if config.frameworks.include?(:action_controller) - config.middleware.use(::Rack::Lock, :if => lambda { ActionController::Base.allow_concurrency }) - config.middleware.use(ActionDispatch::ShowExceptions, lambda { ActionController::Base.consider_all_requests_local }) - config.middleware.use(ActionDispatch::Callbacks, lambda { ActionController::Dispatcher.prepare_each_request }) - config.middleware.use(lambda { ActionController::Base.session_store }, lambda { ActionController::Base.session_options }) - config.middleware.use(ActionDispatch::ParamsParser) - config.middleware.use(::Rack::MethodOverride) - config.middleware.use(::Rack::Head) - config.middleware.use(ActionDispatch::StringCoercion) - end + ActiveSupport::Autoload.eager_load! if config.preload_frameworks end initializer :initialize_cache do @@ -229,12 +155,6 @@ module Rails end end - initializer :initialize_framework_caches do - if config.frameworks.include?(:action_controller) - ActionController::Base.cache_store ||= RAILS_CACHE - end - end - initializer :initialize_logger do # if the environment has explicitly defined a logger, use it next if Rails.logger @@ -265,10 +185,6 @@ module Rails # logger is already set, it is not changed, otherwise it is set to use # RAILS_DEFAULT_LOGGER. initializer :initialize_framework_logging do - for framework in ([ :active_record, :action_controller, :action_mailer ] & config.frameworks) - framework.to_s.camelize.constantize.const_get("Base").logger ||= Rails.logger - end - ActiveSupport::Dependencies.logger ||= Rails.logger Rails.cache.logger ||= Rails.logger end @@ -286,7 +202,7 @@ module Rails require('active_support/whiny_nil') if config.whiny_nils end - # Sets the default value for Time.zone, and turns on ActiveRecord::Base#time_zone_aware_attributes. + # Sets the default value for Time.zone # If assigned value cannot be matched to a TimeZone, an exception will be raised. initializer :initialize_time_zone do if config.time_zone @@ -300,11 +216,6 @@ module Rails end Time.zone_default = zone_default - - if config.frameworks.include?(:active_record) - ActiveRecord::Base.time_zone_aware_attributes = true - ActiveRecord::Base.default_timezone = :utc - end end end @@ -320,118 +231,28 @@ module Rails end end - # Initializes framework-specific settings for each of the loaded frameworks - # (Configuration#frameworks). The available settings map to the accessors - # on each of the corresponding Base classes. - initializer :initialize_framework_settings do - config.frameworks.each do |framework| - base_class = framework.to_s.camelize.constantize.const_get("Base") - - config.send(framework).each do |setting, value| - base_class.send("#{setting}=", value) - end - end - end - - # Sets +ActionController::Base#view_paths+ and +ActionMailer::Base#template_root+ - # (but only for those frameworks that are to be loaded). If the framework's - # paths have already been set, it is not changed, otherwise it is - # set to use Configuration#view_path. - initializer :initialize_framework_views do - if config.frameworks.include?(:action_view) - view_path = ActionView::PathSet.type_cast(config.view_path, config.cache_classes) - ActionMailer::Base.template_root = view_path if config.frameworks.include?(:action_mailer) && ActionMailer::Base.view_paths.blank? - ActionController::Base.view_paths = view_path if config.frameworks.include?(:action_controller) && ActionController::Base.view_paths.blank? - end - end - - initializer :initialize_metal do - # TODO: Make Rails and metal work without ActionController - if config.frameworks.include?(:action_controller) - Rails::Rack::Metal.requested_metals = config.metals - - config.middleware.insert_before( - :"ActionDispatch::ParamsParser", - Rails::Rack::Metal, :if => Rails::Rack::Metal.metals.any?) - end - end - # # bail out if gems are missing - note that check_gem_dependencies will have # # already called abort() unless $gems_rake_task is set # return unless gems_dependencies_loaded initializer :load_application_initializers do - Dir["#{configuration.root}/config/initializers/**/*.rb"].sort.each do |initializer| + Dir["#{root}/config/initializers/**/*.rb"].sort.each do |initializer| load(initializer) end end # Fires the user-supplied after_initialize block (Configuration#after_initialize) initializer :after_initialize do - configuration.after_initialize_blocks.each do |block| + config.after_initialize_blocks.each do |block| block.call end end - # # Setup database middleware after initializers have run - initializer :initialize_database_middleware do - if configuration.frameworks.include?(:active_record) - if configuration.frameworks.include?(:action_controller) && ActionController::Base.session_store && - ActionController::Base.session_store.name == 'ActiveRecord::SessionStore' - configuration.middleware.insert_before :"ActiveRecord::SessionStore", ActiveRecord::ConnectionAdapters::ConnectionManagement - configuration.middleware.insert_before :"ActiveRecord::SessionStore", ActiveRecord::QueryCache - else - configuration.middleware.use ActiveRecord::ConnectionAdapters::ConnectionManagement - configuration.middleware.use ActiveRecord::QueryCache - end - end - end - - # TODO: Make a DSL way to limit an initializer to a particular framework - - # # Prepare dispatcher callbacks and run 'prepare' callbacks - initializer :prepare_dispatcher do - next unless configuration.frameworks.include?(:action_controller) - require 'rails/dispatcher' unless defined?(::Dispatcher) - Dispatcher.define_dispatcher_callbacks(configuration.cache_classes) - - unless configuration.cache_classes - # Setup dev mode route reloading - routes_last_modified = routes_changed_at - reload_routes = lambda do - unless routes_changed_at == routes_last_modified - routes_last_modified = routes_changed_at - reload_routes! - end - end - ActionDispatch::Callbacks.before_dispatch { |callbacks| reload_routes.call } - end - end - - # Routing must be initialized after plugins to allow the former to extend the routes - # --- - # If Action Controller is not one of the loaded frameworks (Configuration#frameworks) - # this does nothing. Otherwise, it loads the routing definitions and sets up - # loading module used to lazily load controllers (Configuration#controller_paths). - initializer :initialize_routing do - next unless configuration.frameworks.include?(:action_controller) - route_configuration_files << configuration.routes_configuration_file - route_configuration_files << configuration.builtin_routes_configuration_file - reload_routes! - end - # - # # Observers are loaded after plugins in case Observers or observed models are modified by plugins. - initializer :load_observers do - if configuration.frameworks.include?(:active_record) - ActiveRecord::Base.instantiate_observers - end - end - # Eager load application classes initializer :load_application_classes do next if $rails_rake_task - if configuration.cache_classes - configuration.eager_load_paths.each do |load_path| + if config.cache_classes + config.eager_load_paths.each do |load_path| matcher = /\A#{Regexp.escape(load_path)}(.*)\.rb\Z/ Dir.glob("#{load_path}/**/*.rb").sort.each do |file| require_dependency file.sub(matcher, '\1') @@ -442,7 +263,7 @@ module Rails # Disable dependency loading during request cycle initializer :disable_dependency_loading do - if configuration.cache_classes && !configuration.dependency_loading + if config.cache_classes && !config.dependency_loading ActiveSupport::Dependencies.unhook! end end diff --git a/railties/lib/rails/commands/server.rb b/railties/lib/rails/commands/server.rb index 3687b4460e..57b7c6a49c 100644 --- a/railties/lib/rails/commands/server.rb +++ b/railties/lib/rails/commands/server.rb @@ -41,9 +41,9 @@ module Rails new(app).start end - def initialize(app_const) + def initialize(app) super() # Call Rack::Server#initialize without passing any options to use. - @app_const = app_const + @app = app end def start @@ -69,7 +69,7 @@ module Rails end def log_path - "#{File.expand_path(@app_const.root)}/log/#{options[:environment]}.log" + "#{File.expand_path(@app.root)}/log/#{options[:environment]}.log" end def default_options @@ -77,10 +77,10 @@ module Rails :Port => 3000, :Host => "0.0.0.0", :environment => (ENV['RAILS_ENV'] || "development").dup, - :rack_file => "#{@app_const.root}/config.ru", + :rack_file => "#{@app.root}/config.ru", :daemonize => false, :debugger => false, - :pid => "#{@app_const.root}/tmp/pids/server.pid", + :pid => "#{@app.root}/tmp/pids/server.pid", :AccessLog => [] } end diff --git a/railties/lib/rails/configuration.rb b/railties/lib/rails/configuration.rb index bf5b9478cc..086f67a419 100644 --- a/railties/lib/rails/configuration.rb +++ b/railties/lib/rails/configuration.rb @@ -5,22 +5,26 @@ module Rails # configuration class while this bit is being cleaned up. class Plugin::Configuration - def initialize - @options = Hash.new { |h,k| h[k] = ActiveSupport::OrderedOptions.new } + def self.default + @default ||= new end - def middleware - @middleware ||= ActionDispatch::MiddlewareStack.new + attr_reader :middleware + + def initialize(base = nil) + if base + @options = base.options.dup + @middleware = base.middleware.dup + else + @options = Hash.new { |h,k| h[k] = ActiveSupport::OrderedOptions.new } + @middleware = ActionDispatch::MiddlewareStack.new + end end def respond_to?(name) super || name.to_s =~ config_key_regexp end - def merge(config) - @options = config.options.merge(@options) - end - protected attr_reader :options @@ -41,8 +45,7 @@ module Rails end def config_keys - ([ :active_support, :active_record, :action_controller, - :action_view, :action_mailer, :active_resource ] + + ([ :active_support, :action_view, :action_mailer, :active_resource ] + Plugin.plugin_names).map { |n| n.to_s }.uniq end end @@ -60,7 +63,7 @@ module Rails :log_level, :log_path, :paths, :routes_configuration_file, :view_path - def initialize + def initialize(base = nil) super @load_once_paths = [] @after_initialize_blocks = [] diff --git a/railties/lib/rails/core.rb b/railties/lib/rails/core.rb index a5e51ad04a..da16c5816c 100644 --- a/railties/lib/rails/core.rb +++ b/railties/lib/rails/core.rb @@ -1,3 +1,37 @@ +require "pathname" + +require 'active_support' +require 'active_support/core_ext/kernel/reporting' +require 'active_support/core_ext/logger' +require 'action_dispatch' + +require 'rails/initializable' +require 'rails/application' +require 'rails/plugin' +require 'rails/railties_path' +require 'rails/version' +require 'rails/rack' +require 'rails/paths' +require 'rails/core' +require 'rails/configuration' +require 'rails/deprecation' +require 'rails/initializer' +require 'rails/ruby_version_check' + +# For Ruby 1.8, this initialization sets $KCODE to 'u' to enable the +# multibyte safe operations. Plugin authors supporting other encodings +# should override this behaviour and set the relevant +default_charset+ +# on ActionController::Base. +# +# For Ruby 1.9, UTF-8 is the default internal and external encoding. +if RUBY_VERSION < '1.9' + $KCODE='u' +else + Encoding.default_external = Encoding::UTF_8 +end + +RAILS_ENV = (ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development").dup unless defined?(RAILS_ENV) + module Rails # Needs to be duplicated from Active Support since its needed before Active # Support is available. Here both Options and Hash are namespaced to prevent diff --git a/railties/lib/rails/generators/rails/app/templates/config.ru b/railties/lib/rails/generators/rails/app/templates/config.ru index f3bf3d6117..acb8435446 100644 --- a/railties/lib/rails/generators/rails/app/templates/config.ru +++ b/railties/lib/rails/generators/rails/app/templates/config.ru @@ -2,4 +2,4 @@ require ::File.expand_path('../config/environment', __FILE__) # Dispatch the request -run <%= app_const%> +run <%= app_const %>.instance diff --git a/railties/lib/rails/generators/rails/app/templates/config/routes.rb b/railties/lib/rails/generators/rails/app/templates/config/routes.rb index ac916e9d90..d6c0365c04 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/routes.rb +++ b/railties/lib/rails/generators/rails/app/templates/config/routes.rb @@ -7,7 +7,7 @@ # Keep in mind you can assign values other than :controller and :action # Sample of named route: - # match 'products/:id/purchase', :to => 'catalog#purchase', :as => :purchase + # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase # This route can be invoked with purchase_url(:id => product.id) # Sample resource route (maps HTTP verbs to controller actions automatically): diff --git a/railties/lib/rails/generators/rails/app/templates/script/console.tt b/railties/lib/rails/generators/rails/app/templates/script/console.tt index 4262439e52..9ddd4cfe62 100755 --- a/railties/lib/rails/generators/rails/app/templates/script/console.tt +++ b/railties/lib/rails/generators/rails/app/templates/script/console.tt @@ -1,3 +1,3 @@ require File.expand_path('../../config/application', __FILE__) require 'rails/commands/console' -Rails::Console.start(<%= app_const %>) +Rails::Console.start(<%= app_const %>.instance) diff --git a/railties/lib/rails/generators/rails/app/templates/script/dbconsole.tt b/railties/lib/rails/generators/rails/app/templates/script/dbconsole.tt index 9dfa24c378..96e0bc191b 100755 --- a/railties/lib/rails/generators/rails/app/templates/script/dbconsole.tt +++ b/railties/lib/rails/generators/rails/app/templates/script/dbconsole.tt @@ -1,3 +1,3 @@ require File.expand_path('../../config/application', __FILE__) require 'rails/commands/dbconsole' -Rails::DBConsole.start(<%= app_const %>)
\ No newline at end of file +Rails::DBConsole.start(<%= app_const %>.instance) diff --git a/railties/lib/rails/generators/rails/app/templates/script/server.tt b/railties/lib/rails/generators/rails/app/templates/script/server.tt index d98f677475..380dc42cb5 100755 --- a/railties/lib/rails/generators/rails/app/templates/script/server.tt +++ b/railties/lib/rails/generators/rails/app/templates/script/server.tt @@ -1,3 +1,3 @@ require File.expand_path('../../config/application', __FILE__) require 'rails/commands/server' -Rails::Server.start(<%= app_const %>) +Rails::Server.start(<%= app_const %>.instance) diff --git a/railties/lib/rails/initializable.rb b/railties/lib/rails/initializable.rb index add10bd207..8fcb254590 100644 --- a/railties/lib/rails/initializable.rb +++ b/railties/lib/rails/initializable.rb @@ -93,6 +93,7 @@ module Rails end def initializer(name, opts = {}, &blk) + raise ArgumentError, "A block must be passed when defining an initializer" unless blk @initializers ||= [] @initializers << Initializer.new(name, nil, opts, &blk) end diff --git a/railties/lib/rails/plugin.rb b/railties/lib/rails/plugin.rb index 90dc1ad8dd..0699affea7 100644 --- a/railties/lib/rails/plugin.rb +++ b/railties/lib/rails/plugin.rb @@ -2,8 +2,10 @@ module Rails class Plugin include Initializable - def self.plugin_name - @plugin_name || name.demodulize.underscore + def self.plugin_name(plugin_name = nil) + @plugin_name ||= name.demodulize.underscore + @plugin_name = plugin_name if plugin_name + @plugin_name end def self.inherited(klass) @@ -20,7 +22,7 @@ module Rails end def self.config - @config ||= Configuration.new + Configuration.default end class Vendored < Plugin diff --git a/railties/lib/rails/test_help.rb b/railties/lib/rails/test_help.rb index b89b7b5c27..2601765065 100644 --- a/railties/lib/rails/test_help.rb +++ b/railties/lib/rails/test_help.rb @@ -2,9 +2,8 @@ # so fixtures are loaded to the right database silence_warnings { RAILS_ENV = "test" } -require 'rubygems' -gem "rack", "~> 1.0.0" -gem "rack-test", "~> 0.5.0" +require 'rack' +require 'rack/test' require 'test/unit' require 'active_support/core_ext/kernel/requires' diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 83e1401993..4d9da525d7 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -4,7 +4,16 @@ module ApplicationTests class InitializerTest < Test::Unit::TestCase include ActiveSupport::Testing::Isolation + def new_app + File.expand_path("#{app_path}/../new_app") + end + + def copy_app + FileUtils.cp_r(app_path, new_app) + end + def setup + FileUtils.rm_rf(new_app) if File.directory?(new_app) build_app boot_rails end @@ -15,42 +24,42 @@ module ApplicationTests end test "the application root can be set" do - FileUtils.mkdir_p("#{app_path}/hello") + copy_app add_to_config <<-RUBY - config.frameworks = [] - config.root = '#{app_path}/hello' + config.root = '#{new_app}' RUBY - require "#{app_path}/config/environment" - assert_equal Pathname.new("#{app_path}/hello"), Rails.application.root - end - test "the application root is detected as where config.ru is located" do - add_to_config <<-RUBY - config.frameworks = [] - RUBY - FileUtils.mv "#{app_path}/config.ru", "#{app_path}/config/config.ru" + use_frameworks [] + require "#{app_path}/config/environment" - assert_equal Pathname.new("#{app_path}/config"), Rails.application.root + assert_equal Pathname.new(new_app), Rails.application.root end test "the application root is Dir.pwd if there is no config.ru" do File.delete("#{app_path}/config.ru") - add_to_config <<-RUBY - config.frameworks = [] - RUBY - Dir.chdir("#{app_path}/app") do + use_frameworks [] + + Dir.chdir("#{app_path}") do require "#{app_path}/config/environment" - assert_equal Pathname.new("#{app_path}/app"), Rails.application.root + assert_equal Pathname.new("#{app_path}"), Rails.application.root end end + test "if there's no config.active_support.bare, all of ActiveSupport is required" do + use_frameworks [] + require "#{app_path}/config/environment" + assert_nothing_raised { [1,2,3].rand } + end + test "config.active_support.bare does not require all of ActiveSupport" do - add_to_config "config.frameworks = []; config.active_support.bare = true" + add_to_config "config.active_support.bare = true" + + use_frameworks [] Dir.chdir("#{app_path}/app") do require "#{app_path}/config/environment" - assert_raises(NoMethodError) { 1.day } + assert_raises(NoMethodError) { [1,2,3].rand } end end @@ -60,7 +69,7 @@ module ApplicationTests RUBY require "#{app_path}/config/application" - assert AppTemplate::Application.configuration.action_controller.allow_concurrency + assert AppTemplate::Application.config.action_controller.allow_concurrency end test "the application can be marked as threadsafe when there are no frameworks" do diff --git a/railties/test/application/generators_test.rb b/railties/test/application/generators_test.rb index 2ed49d1057..7b27c780aa 100644 --- a/railties/test/application/generators_test.rb +++ b/railties/test/application/generators_test.rb @@ -7,8 +7,6 @@ module ApplicationTests def setup build_app boot_rails - require "rails" - require "rails/generators" end def app_const @@ -16,6 +14,8 @@ module ApplicationTests end def with_config + require "rails" + require "rails/generators" yield app_const.config end @@ -46,14 +46,15 @@ module ApplicationTests end test "generators aliases and options on initialization" do - application = with_config do |c| - c.frameworks = [] - c.generators.rails :aliases => { :test_framework => "-w" } - c.generators.orm :datamapper - c.generators.test_framework :rspec - end + add_to_config <<-RUBY + config.generators.rails :aliases => { :test_framework => "-w" } + config.generators.orm :datamapper + config.generators.test_framework :rspec + RUBY + + require "#{app_path}/config/environment" # Initialize the application - app_const.initialize! + require "rails/generators" Rails::Generators.configure! assert_equal :rspec, Rails::Generators.options[:rails][:test_framework] @@ -61,12 +62,13 @@ module ApplicationTests end test "generators no color on initialization" do - with_config do |c| - c.frameworks = [] - c.generators.colorize_logging = false - end + add_to_config <<-RUBY + config.generators.colorize_logging = false + RUBY + # Initialize the application - app_const.initialize! + require "#{app_path}/config/environment" + require "rails/generators" Rails::Generators.configure! assert_equal Thor::Base.shell, Thor::Shell::Basic diff --git a/railties/test/application/initializer_test.rb b/railties/test/application/initializer_test.rb index b3eff1deb9..2ecc3e9e2d 100644 --- a/railties/test/application/initializer_test.rb +++ b/railties/test/application/initializer_test.rb @@ -19,19 +19,6 @@ module ApplicationTests assert $:.include?("#{app_path}/app/models") end - test "adding an unknown framework raises an error" do - add_to_config <<-RUBY - config.root = "#{app_path}" - config.frameworks << :action_foo - RUBY - - require "active_support/core_ext/load_error" - - assert_raises MissingSourceFile do - require "#{app_path}/config/environment" - end - end - test "eager loading loads parent classes before children" do app_file "lib/zoo.rb", <<-ZOO class Zoo ; include ReptileHouse ; end @@ -148,21 +135,9 @@ module ApplicationTests assert !Rails.application.config.middleware.include?(ActiveRecord::SessionStore) end - test "database middleware doesn't initialize when activerecord is not in frameworks" do - add_to_config <<-RUBY - config.root = "#{app_path}" - config.frameworks = [] - RUBY - require "#{app_path}/config/environment" - - assert_equal [], Rails.application.config.middleware - end - test "database middleware initializes when session store is active record" do - add_to_config <<-RUBY - config.root = "#{app_path}" - config.action_controller.session_store = :active_record_store - RUBY + add_to_config "config.action_controller.session_store = :active_record_store" + require "#{app_path}/config/environment" expects = [ActiveRecord::ConnectionAdapters::ConnectionManagement, ActiveRecord::QueryCache, ActiveRecord::SessionStore] @@ -170,35 +145,28 @@ module ApplicationTests assert_equal expects, middleware & expects end - test "ensure database middleware doesn't use action_controller on initializing" do + test "Rails.root should be a Pathname" do add_to_config <<-RUBY config.root = "#{app_path}" - config.frameworks -= [:action_controller] - config.action_controller.session_store = :active_record_store RUBY require "#{app_path}/config/environment" - - assert !Rails.application.config.middleware.include?(ActiveRecord::SessionStore) + assert_instance_of Pathname, Rails.root end + end - # Pathview test - test "load view paths doesn't perform anything when action_view not in frameworks" do - add_to_config <<-RUBY - config.root = "#{app_path}" - config.frameworks -= [:action_view] - RUBY - require "#{app_path}/config/environment" + class InitializerCustomFrameworkExtensionsTest < Test::Unit::TestCase + include ActiveSupport::Testing::Isolation - assert_equal nil, ActionMailer::Base.template_root - assert_equal [], ActionController::Base.view_paths + def setup + build_app + boot_rails end - test "Rails.root should be a Pathname" do - add_to_config <<-RUBY - config.root = "#{app_path}" - RUBY + test "database middleware doesn't initialize when activerecord is not in frameworks" do + use_frameworks [] require "#{app_path}/config/environment" - assert_instance_of Pathname, Rails.root + + assert !defined?(ActiveRecord) end end end
\ No newline at end of file diff --git a/railties/test/application/load_test.rb b/railties/test/application/load_test.rb index e17f1ebdb0..1c5811b07a 100644 --- a/railties/test/application/load_test.rb +++ b/railties/test/application/load_test.rb @@ -1,6 +1,4 @@ require "isolation/abstract_unit" -# require "rails" -# require 'action_dispatch' module ApplicationTests class LoadTest < Test::Unit::TestCase @@ -22,8 +20,10 @@ module ApplicationTests end test "config.ru can be racked up" do - @app = rackup - assert_welcome get("/") + Dir.chdir app_path do + @app = rackup + assert_welcome get("/") + end end test "Rails.application is available after config.ru has been racked up" do diff --git a/railties/test/application/routing_test.rb b/railties/test/application/routing_test.rb index 7b1df7f45d..725dd06929 100644 --- a/railties/test/application/routing_test.rb +++ b/railties/test/application/routing_test.rb @@ -1,24 +1,29 @@ require 'isolation/abstract_unit' -require 'rack/test' module ApplicationTests class RoutingTest < Test::Unit::TestCase include ActiveSupport::Testing::Isolation - include Rack::Test::Methods def setup build_app + boot_rails + require 'rack/test' + extend Rack::Test::Methods end def app @app ||= begin - boot_rails require "#{app_path}/config/environment" Rails.application end end + test "rails/info/properties" do + get "/rails/info/properties" + assert_equal 200, last_response.status + end + test "simple controller" do controller :foo, <<-RUBY class FooController < ActionController::Base @@ -166,6 +171,8 @@ module ApplicationTests end RUBY + sleep 0.1 + get '/foo' assert_equal 'baz', last_response.body end diff --git a/railties/test/initializable_test.rb b/railties/test/initializable_test.rb index a9e60680ac..e308cbcb0e 100644 --- a/railties/test/initializable_test.rb +++ b/railties/test/initializable_test.rb @@ -150,6 +150,16 @@ module InitializableTests Word.run_initializers assert_equal "bird", $word end + + test "creating initializer without a block raises an error" do + assert_raise(ArgumentError) do + Class.new do + include Rails::Initializable + + initializer :foo + end + end + end end class BeforeAfter < ActiveSupport::TestCase diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb index c169c80bea..ee0a812b47 100644 --- a/railties/test/isolation/abstract_unit.rb +++ b/railties/test/isolation/abstract_unit.rb @@ -153,6 +153,14 @@ module TestHelpers app_file("app/controllers/#{name}_controller.rb", contents) end + def use_frameworks(arr) + to_remove = [:actionmailer, + :activemodel, + :activerecord, + :activeresource] - arr + $:.reject! {|path| path =~ %r'/(#{to_remove.join('|')})/' } + end + def boot_rails root = File.expand_path('../../../..', __FILE__) begin diff --git a/railties/test/plugins/framework_extension_test.rb b/railties/test/plugins/framework_extension_test.rb new file mode 100644 index 0000000000..87e19cadce --- /dev/null +++ b/railties/test/plugins/framework_extension_test.rb @@ -0,0 +1,18 @@ +require "isolation/abstract_unit" + +module PluginsTest + class FrameworkExtensionTest < Test::Unit::TestCase + def setup + build_app + boot_rails + end + + test "active_record extensions are applied to ActiveRecord" do + add_to_config "config.active_record.table_name_prefix = 'tbl_'" + + require "#{app_path}/config/environment" + + assert_equal 'tbl_', ActiveRecord::Base.table_name_prefix + end + end +end
\ No newline at end of file |