aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Gemfile5
-rw-r--r--actionmailer/lib/action_mailer.rb15
-rw-r--r--actionmailer/lib/action_mailer/base.rb63
-rw-r--r--actionmailer/lib/action_mailer/delivery_method.rb5
-rw-r--r--actionmailer/lib/action_mailer/delivery_method/smtp.rb4
-rw-r--r--actionmailer/lib/action_mailer/rails.rb24
-rw-r--r--actionmailer/test/mail_service_test.rb8
-rw-r--r--actionmailer/test/url_test.rb4
-rw-r--r--actionpack/actionpack.gemspec4
-rw-r--r--actionpack/lib/abstract_controller.rb16
-rw-r--r--actionpack/lib/abstract_controller/base.rb8
-rw-r--r--actionpack/lib/abstract_controller/logger.rb28
-rw-r--r--actionpack/lib/action_controller.rb111
-rw-r--r--actionpack/lib/action_controller/base.rb3
-rw-r--r--actionpack/lib/action_controller/caching.rb12
-rw-r--r--actionpack/lib/action_controller/metal.rb2
-rw-r--r--actionpack/lib/action_controller/metal/benchmarking.rb1
-rw-r--r--actionpack/lib/action_controller/metal/logger.rb34
-rw-r--r--actionpack/lib/action_controller/metal/rack_delegation.rb3
-rw-r--r--actionpack/lib/action_controller/metal/redirecting.rb8
-rw-r--r--actionpack/lib/action_controller/notifications.rb10
-rw-r--r--actionpack/lib/action_controller/rails.rb102
-rw-r--r--actionpack/lib/action_controller/vendor/html-scanner.rb26
-rw-r--r--actionpack/lib/action_dispatch.rb55
-rwxr-xr-xactionpack/lib/action_dispatch/http/request.rb2
-rw-r--r--actionpack/lib/action_dispatch/http/response.rb4
-rw-r--r--actionpack/lib/action_dispatch/http/status_codes.rb33
-rw-r--r--actionpack/lib/action_dispatch/middleware/params_parser.rb1
-rw-r--r--actionpack/lib/action_dispatch/middleware/session/abstract_store.rb1
-rw-r--r--actionpack/lib/action_dispatch/middleware/session/cookie_store.rb9
-rw-r--r--actionpack/lib/action_dispatch/middleware/show_exceptions.rb5
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb227
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb2
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/dom.rb4
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/response.rb2
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/selector.rb22
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/tag.rb2
-rw-r--r--actionpack/lib/action_dispatch/testing/integration.rb4
-rw-r--r--actionpack/lib/action_view.rb41
-rw-r--r--actionpack/lib/action_view/helpers/sanitize_helper.rb1
-rw-r--r--actionpack/lib/action_view/helpers/translation_helper.rb2
-rw-r--r--actionpack/lib/action_view/safe_buffer.rb1
-rw-r--r--actionpack/lib/action_view/template.rb29
-rw-r--r--actionpack/lib/action_view/template/handlers/erb.rb3
-rw-r--r--actionpack/test/controller/render_test.rb4
-rw-r--r--actionpack/test/dispatch/response_test.rb4
-rw-r--r--actionpack/test/dispatch/routing_test.rb24
-rw-r--r--activemodel/lib/active_model/validations.rb1
-rw-r--r--activerecord/lib/active_record.rb116
-rw-r--r--activerecord/lib/active_record/notifications.rb5
-rw-r--r--activerecord/lib/active_record/rails.rb59
-rw-r--r--activeresource/lib/active_resource/base.rb3
-rw-r--r--activeresource/test/cases/base/schema_test.rb1
-rw-r--r--activesupport/lib/active_support.rb53
-rw-r--r--activesupport/lib/active_support/core_ext/string/output_safety.rb29
-rw-r--r--activesupport/lib/active_support/dependencies/autoload.rb10
-rw-r--r--activesupport/lib/active_support/json/encoding.rb13
-rw-r--r--activesupport/lib/active_support/whiny_nil.rb5
-rw-r--r--activesupport/test/json/encoding_test.rb4
-rw-r--r--railties/builtin/routes.rb2
-rw-r--r--railties/lib/rails.rb42
-rw-r--r--railties/lib/rails/application.rb265
-rw-r--r--railties/lib/rails/commands/server.rb10
-rw-r--r--railties/lib/rails/configuration.rb25
-rw-r--r--railties/lib/rails/core.rb34
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config.ru2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/routes.rb2
-rwxr-xr-xrailties/lib/rails/generators/rails/app/templates/script/console.tt2
-rwxr-xr-xrailties/lib/rails/generators/rails/app/templates/script/dbconsole.tt2
-rwxr-xr-xrailties/lib/rails/generators/rails/app/templates/script/server.tt2
-rw-r--r--railties/lib/rails/initializable.rb1
-rw-r--r--railties/lib/rails/plugin.rb8
-rw-r--r--railties/lib/rails/test_help.rb5
-rw-r--r--railties/test/application/configuration_test.rb49
-rw-r--r--railties/test/application/generators_test.rb30
-rw-r--r--railties/test/application/initializer_test.rb60
-rw-r--r--railties/test/application/load_test.rb8
-rw-r--r--railties/test/application/routing_test.rb13
-rw-r--r--railties/test/initializable_test.rb10
-rw-r--r--railties/test/isolation/abstract_unit.rb8
-rw-r--r--railties/test/plugins/framework_extension_test.rb18
81 files changed, 960 insertions, 915 deletions
diff --git a/Gemfile b/Gemfile
index d979add5b3..361074dce6 100644
--- a/Gemfile
+++ b/Gemfile
@@ -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