mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Reorganize autoloads:
* A new module (ActiveSupport::Autoload) is provide that extends autoloading with new behavior. * All autoloads in modules that have extended ActiveSupport::Autoload will be eagerly required in threadsafe environments * Autoloads can optionally leave off the path if the path is the same as full_constant_name.underscore * It is possible to specify that a group of autoloads live under an additional path. For instance, all of ActionDispatch's middlewares are ActionDispatch::MiddlewareName, but they live under "action_dispatch/middlewares/middleware_name" * It is possible to specify that a group of autoloads are all found at the same path. For instance, a number of exceptions might all be declared there. * One consequence of this is that testing-related constants are not autoloaded. To get the testing helpers for a given component, require "component_name/test_case". For instance, "action_controller/test_case". * test_help.rb, which is automatically required by a Rails application's test helper, requires the test_case.rb for all active components, so this change will not be disruptive in existing or new applications.
This commit is contained in:
parent
399909b11c
commit
c1304098cc
52 changed files with 1018 additions and 822 deletions
|
@ -25,32 +25,34 @@ actionpack_path = "#{File.dirname(__FILE__)}/../../actionpack/lib"
|
|||
$:.unshift(actionpack_path) if File.directory?(actionpack_path)
|
||||
require 'action_controller'
|
||||
require 'action_view'
|
||||
require 'active_support/autoload'
|
||||
|
||||
module ActionMailer
|
||||
def self.load_all!
|
||||
[Base, Part, ::Text::Format, ::Net::SMTP]
|
||||
end
|
||||
extend ::ActiveSupport::Autoload
|
||||
|
||||
autoload :AdvAttrAccessor, 'action_mailer/adv_attr_accessor'
|
||||
autoload :DeprecatedBody, 'action_mailer/deprecated_body'
|
||||
autoload :Base, 'action_mailer/base'
|
||||
autoload :DeliveryMethod, 'action_mailer/delivery_method'
|
||||
autoload :Part, 'action_mailer/part'
|
||||
autoload :PartContainer, 'action_mailer/part_container'
|
||||
autoload :Quoting, 'action_mailer/quoting'
|
||||
autoload :TestCase, 'action_mailer/test_case'
|
||||
autoload :TestHelper, 'action_mailer/test_helper'
|
||||
autoload :Utils, 'action_mailer/utils'
|
||||
autoload :AdvAttrAccessor
|
||||
autoload :DeprecatedBody
|
||||
autoload :Base
|
||||
autoload :DeliveryMethod
|
||||
autoload :MailHelper
|
||||
autoload :Part
|
||||
autoload :PartContainer
|
||||
autoload :Quoting
|
||||
autoload :TestHelper
|
||||
autoload :Utils
|
||||
end
|
||||
|
||||
module Text
|
||||
extend ActiveSupport::Autoload
|
||||
|
||||
autoload :Format, 'action_mailer/vendor/text_format'
|
||||
end
|
||||
|
||||
module Net
|
||||
autoload :SMTP, 'net/smtp'
|
||||
extend ActiveSupport::Autoload
|
||||
|
||||
autoload :SMTP
|
||||
end
|
||||
|
||||
autoload :MailHelper, 'action_mailer/mail_helper'
|
||||
|
||||
require 'action_mailer/vendor/tmail'
|
||||
|
|
|
@ -258,7 +258,7 @@ module ActionMailer #:nodoc:
|
|||
include AbstractController::Layouts
|
||||
|
||||
include AbstractController::Helpers
|
||||
helper MailHelper
|
||||
helper ActionMailer::MailHelper
|
||||
|
||||
if Object.const_defined?(:ActionController)
|
||||
include ActionController::UrlWriter
|
||||
|
|
|
@ -6,7 +6,7 @@ module ActionMailer
|
|||
# A delivery method implementation which writes all mails to a file.
|
||||
class File < Method
|
||||
self.settings = {
|
||||
:location => defined?(Rails) ? "#{Rails.root}/tmp/mails" : "#{Dir.tmpdir}/mails"
|
||||
:location => defined?(Rails.root) ? "#{Rails.root}/tmp/mails" : "#{Dir.tmpdir}/mails"
|
||||
}
|
||||
|
||||
def perform_delivery(mail)
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
module MailHelper
|
||||
# Uses Text::Format to take the text and format it, indented two spaces for
|
||||
# each line, and wrapped at 72 columns.
|
||||
def block_format(text)
|
||||
formatted = text.split(/\n\r\n/).collect { |paragraph|
|
||||
Text::Format.new(
|
||||
:columns => 72, :first_indent => 2, :body_indent => 2, :text => paragraph
|
||||
).format
|
||||
}.join("\n")
|
||||
module ActionMailer
|
||||
module MailHelper
|
||||
# Uses Text::Format to take the text and format it, indented two spaces for
|
||||
# each line, and wrapped at 72 columns.
|
||||
def block_format(text)
|
||||
formatted = text.split(/\n\r\n/).collect { |paragraph|
|
||||
Text::Format.new(
|
||||
:columns => 72, :first_indent => 2, :body_indent => 2, :text => paragraph
|
||||
).format
|
||||
}.join("\n")
|
||||
|
||||
# Make list points stand on their own line
|
||||
formatted.gsub!(/[ ]*([*]+) ([^*]*)/) { |s| " #{$1} #{$2.strip}\n" }
|
||||
formatted.gsub!(/[ ]*([#]+) ([^#]*)/) { |s| " #{$1} #{$2.strip}\n" }
|
||||
# Make list points stand on their own line
|
||||
formatted.gsub!(/[ ]*([*]+) ([^*]*)/) { |s| " #{$1} #{$2.strip}\n" }
|
||||
formatted.gsub!(/[ ]*([#]+) ([^#]*)/) { |s| " #{$1} #{$2.strip}\n" }
|
||||
|
||||
formatted
|
||||
formatted
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -2,15 +2,20 @@ require "active_support/core_ext/module/attr_internal"
|
|||
require "active_support/core_ext/module/delegation"
|
||||
|
||||
module AbstractController
|
||||
autoload :Base, "abstract_controller/base"
|
||||
autoload :Callbacks, "abstract_controller/callbacks"
|
||||
autoload :Helpers, "abstract_controller/helpers"
|
||||
autoload :Layouts, "abstract_controller/layouts"
|
||||
autoload :LocalizedCache, "abstract_controller/localized_cache"
|
||||
autoload :Logger, "abstract_controller/logger"
|
||||
autoload :RenderingController, "abstract_controller/rendering_controller"
|
||||
extend ActiveSupport::Autoload
|
||||
|
||||
autoload :Base
|
||||
autoload :Callbacks
|
||||
autoload :Helpers
|
||||
autoload :Layouts
|
||||
autoload :LocalizedCache
|
||||
autoload :Logger
|
||||
autoload :RenderingController
|
||||
|
||||
# === Exceptions
|
||||
autoload :ActionNotFound, "abstract_controller/exceptions"
|
||||
autoload :DoubleRenderError, "abstract_controller/exceptions"
|
||||
autoload :Error, "abstract_controller/exceptions"
|
||||
autoload_at "abstract_controller/exceptions" do
|
||||
autoload :ActionNotFound
|
||||
autoload :DoubleRenderError
|
||||
autoload :Error
|
||||
end
|
||||
end
|
||||
|
|
|
@ -115,7 +115,7 @@ module AbstractController
|
|||
# _partial<TrueClass, FalseClass>:: Whether or not the file to look up is a partial
|
||||
def _determine_template(options)
|
||||
if options.key?(:text)
|
||||
options[:_template] = ActionView::TextTemplate.new(options[:text], format_for_text)
|
||||
options[:_template] = ActionView::Template::Text.new(options[:text], format_for_text)
|
||||
elsif options.key?(:inline)
|
||||
handler = ActionView::Template.handler_class_for_extension(options[:type] || "erb")
|
||||
template = ActionView::Template.new(options[:inline], "inline #{options[:inline].inspect}", handler, {})
|
||||
|
|
|
@ -1,66 +1,72 @@
|
|||
require "active_support"
|
||||
|
||||
module ActionController
|
||||
autoload :Base, "action_controller/base"
|
||||
autoload :Benchmarking, "action_controller/metal/benchmarking"
|
||||
autoload :ConditionalGet, "action_controller/metal/conditional_get"
|
||||
autoload :Configuration, "action_controller/metal/configuration"
|
||||
autoload :Head, "action_controller/metal/head"
|
||||
autoload :Helpers, "action_controller/metal/helpers"
|
||||
autoload :HideActions, "action_controller/metal/hide_actions"
|
||||
autoload :Layouts, "action_controller/metal/layouts"
|
||||
autoload :Metal, "action_controller/metal"
|
||||
autoload :Middleware, "action_controller/middleware"
|
||||
autoload :RackConvenience, "action_controller/metal/rack_convenience"
|
||||
autoload :Rails2Compatibility, "action_controller/metal/compatibility"
|
||||
autoload :Redirector, "action_controller/metal/redirector"
|
||||
autoload :RenderingController, "action_controller/metal/rendering_controller"
|
||||
autoload :RenderOptions, "action_controller/metal/render_options"
|
||||
autoload :Rescue, "action_controller/metal/rescuable"
|
||||
autoload :Responder, "action_controller/metal/responder"
|
||||
autoload :Session, "action_controller/metal/session"
|
||||
autoload :Testing, "action_controller/metal/testing"
|
||||
autoload :UrlFor, "action_controller/metal/url_for"
|
||||
extend ActiveSupport::Autoload
|
||||
|
||||
autoload :Caching, 'action_controller/caching'
|
||||
autoload :Dispatcher, 'action_controller/dispatch/dispatcher'
|
||||
autoload :Integration, 'action_controller/deprecated/integration_test'
|
||||
autoload :IntegrationTest, 'action_controller/deprecated/integration_test'
|
||||
autoload :MimeResponds, 'action_controller/metal/mime_responds'
|
||||
autoload :PerformanceTest, 'action_controller/deprecated/performance_test'
|
||||
autoload :PolymorphicRoutes, 'action_controller/polymorphic_routes'
|
||||
autoload :RecordIdentifier, 'action_controller/record_identifier'
|
||||
autoload :Routing, 'action_controller/deprecated'
|
||||
autoload :SessionManagement, 'action_controller/metal/session_management'
|
||||
autoload :TestCase, 'action_controller/testing/test_case'
|
||||
autoload :TestProcess, 'action_controller/testing/process'
|
||||
autoload :UrlRewriter, 'action_controller/url_rewriter'
|
||||
autoload :UrlWriter, 'action_controller/url_rewriter'
|
||||
autoload :Base
|
||||
autoload :Caching
|
||||
autoload :PolymorphicRoutes
|
||||
autoload :RecordIdentifier
|
||||
autoload :UrlRewriter
|
||||
autoload :Translation
|
||||
autoload :Metal
|
||||
autoload :Middleware
|
||||
|
||||
autoload :Verification, 'action_controller/metal/verification'
|
||||
autoload :Flash, 'action_controller/metal/flash'
|
||||
autoload :RequestForgeryProtection, 'action_controller/metal/request_forgery_protection'
|
||||
autoload :Streaming, 'action_controller/metal/streaming'
|
||||
autoload :HttpAuthentication, 'action_controller/metal/http_authentication'
|
||||
autoload :FilterParameterLogging, 'action_controller/metal/filter_parameter_logging'
|
||||
autoload :Translation, 'action_controller/translation'
|
||||
autoload :Cookies, 'action_controller/metal/cookies'
|
||||
autoload_under "metal" do
|
||||
autoload :Benchmarking
|
||||
autoload :ConditionalGet
|
||||
autoload :Configuration
|
||||
autoload :Head
|
||||
autoload :Helpers
|
||||
autoload :HideActions
|
||||
autoload :Layouts
|
||||
autoload :MimeResponds
|
||||
autoload :RackConvenience
|
||||
autoload :Compatibility
|
||||
autoload :Redirector
|
||||
autoload :RenderingController
|
||||
autoload :RenderOptions
|
||||
autoload :Rescue
|
||||
autoload :Responder
|
||||
autoload :Session
|
||||
autoload :SessionManagement
|
||||
autoload :UrlFor
|
||||
autoload :Verification
|
||||
autoload :Flash
|
||||
autoload :RequestForgeryProtection
|
||||
autoload :Streaming
|
||||
autoload :HttpAuthentication
|
||||
autoload :FilterParameterLogging
|
||||
autoload :Cookies
|
||||
end
|
||||
|
||||
autoload :ActionControllerError, 'action_controller/metal/exceptions'
|
||||
autoload :RenderError, 'action_controller/metal/exceptions'
|
||||
autoload :RoutingError, 'action_controller/metal/exceptions'
|
||||
autoload :MethodNotAllowed, 'action_controller/metal/exceptions'
|
||||
autoload :NotImplemented, 'action_controller/metal/exceptions'
|
||||
autoload :UnknownController, 'action_controller/metal/exceptions'
|
||||
autoload :MissingFile, 'action_controller/metal/exceptions'
|
||||
autoload :RenderError, 'action_controller/metal/exceptions'
|
||||
autoload :SessionOverflowError, 'action_controller/metal/exceptions'
|
||||
autoload :UnknownHttpMethod, 'action_controller/metal/exceptions'
|
||||
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 :UrlWriter, 'action_controller/url_rewriter'
|
||||
|
||||
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
|
||||
|
||||
autoload :HTML, 'action_controller/vendor/html-scanner'
|
||||
autoload :AbstractController, 'abstract_controller'
|
||||
|
||||
# All of these simply register additional autoloads
|
||||
require 'abstract_controller'
|
||||
require 'action_dispatch'
|
||||
require 'action_view'
|
||||
require 'action_controller/vendor/html-scanner'
|
||||
|
||||
# Common ActiveSupport usage in ActionController
|
||||
require "active_support/concern"
|
||||
|
|
|
@ -24,7 +24,7 @@ module ActionController
|
|||
include ActionController::MimeResponds
|
||||
|
||||
# Rails 2.x compatibility
|
||||
include ActionController::Rails2Compatibility
|
||||
include ActionController::Compatibility
|
||||
|
||||
include ActionController::Cookies
|
||||
include ActionController::Session
|
||||
|
|
|
@ -30,10 +30,11 @@ module ActionController #:nodoc:
|
|||
# config.action_controller.cache_store = MyOwnStore.new("parameter")
|
||||
module Caching
|
||||
extend ActiveSupport::Concern
|
||||
extend ActiveSupport::Autoload
|
||||
|
||||
autoload :Actions, 'action_controller/caching/actions'
|
||||
autoload :Fragments, 'action_controller/caching/fragments'
|
||||
autoload :Pages, 'action_controller/caching/pages'
|
||||
autoload :Actions
|
||||
autoload :Fragments
|
||||
autoload :Pages
|
||||
autoload :Sweeper, 'action_controller/caching/sweeping'
|
||||
autoload :Sweeping, 'action_controller/caching/sweeping'
|
||||
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
require "action_dispatch/testing/integration"
|
||||
|
||||
ActionController::Integration = ActionDispatch::Integration
|
||||
ActionController::IntegrationTest = ActionDispatch::IntegrationTest
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
module ActionController
|
||||
module Rails2Compatibility
|
||||
module Compatibility
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
class ::ActionController::ActionControllerError < StandardError #:nodoc:
|
||||
|
|
|
@ -52,7 +52,7 @@ module ActionController
|
|||
included do
|
||||
# Set the default directory for helpers
|
||||
extlib_inheritable_accessor(:helpers_dir) do
|
||||
defined?(Rails) ? "#{Rails.root}/app/helpers" : "app/helpers"
|
||||
defined?(Rails.root) ? "#{Rails.root}/app/helpers" : "app/helpers"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
require 'active_support/test_case'
|
||||
require 'rack/session/abstract/id'
|
||||
require 'action_controller/metal/testing'
|
||||
require 'action_controller/testing/process'
|
||||
require 'action_dispatch/test_case'
|
||||
|
||||
module ActionController
|
||||
class TestRequest < ActionDispatch::TestRequest #:nodoc:
|
|
@ -1,6 +1,8 @@
|
|||
$LOAD_PATH << "#{File.dirname(__FILE__)}/html-scanner"
|
||||
|
||||
module HTML
|
||||
extend ActiveSupport::Autoload
|
||||
|
||||
autoload :CDATA, 'html/node'
|
||||
autoload :Document, 'html/document'
|
||||
autoload :FullSanitizer, 'html/sanitizer'
|
||||
|
|
|
@ -28,37 +28,38 @@ module Rack
|
|||
end
|
||||
|
||||
module ActionDispatch
|
||||
autoload :Request, 'action_dispatch/http/request'
|
||||
autoload :Response, 'action_dispatch/http/response'
|
||||
autoload :StatusCodes, 'action_dispatch/http/status_codes'
|
||||
autoload :Utils, 'action_dispatch/http/utils'
|
||||
extend ActiveSupport::Autoload
|
||||
|
||||
autoload_under "http" do
|
||||
autoload :Request
|
||||
autoload :Response
|
||||
autoload :StatusCodes
|
||||
autoload :Utils
|
||||
end
|
||||
|
||||
autoload_under "middleware" do
|
||||
autoload :Callbacks
|
||||
autoload :ParamsParser
|
||||
autoload :Rescue
|
||||
autoload :ShowExceptions
|
||||
autoload :Static
|
||||
autoload :StringCoercion
|
||||
end
|
||||
|
||||
autoload :Callbacks, 'action_dispatch/middleware/callbacks'
|
||||
autoload :MiddlewareStack, 'action_dispatch/middleware/stack'
|
||||
autoload :ParamsParser, 'action_dispatch/middleware/params_parser'
|
||||
autoload :Rescue, 'action_dispatch/middleware/rescue'
|
||||
autoload :ShowExceptions, 'action_dispatch/middleware/show_exceptions'
|
||||
autoload :Static, 'action_dispatch/middleware/static'
|
||||
autoload :StringCoercion, 'action_dispatch/middleware/string_coercion'
|
||||
|
||||
autoload :Routing, 'action_dispatch/routing'
|
||||
|
||||
autoload :Assertions, 'action_dispatch/testing/assertions'
|
||||
autoload :Integration, 'action_dispatch/testing/integration'
|
||||
autoload :IntegrationTest, 'action_dispatch/testing/integration'
|
||||
autoload :PerformanceTest, 'action_dispatch/testing/performance_test'
|
||||
autoload :TestRequest, 'action_dispatch/testing/test_request'
|
||||
autoload :TestResponse, 'action_dispatch/testing/test_response'
|
||||
autoload :Routing
|
||||
|
||||
autoload :HTML, 'action_controller/vendor/html-scanner'
|
||||
|
||||
module Http
|
||||
autoload :Headers, 'action_dispatch/http/headers'
|
||||
extend ActiveSupport::Autoload
|
||||
|
||||
autoload :Headers
|
||||
end
|
||||
|
||||
module Session
|
||||
autoload :AbstractStore, 'action_dispatch/middleware/session/abstract_store'
|
||||
autoload :CookieStore, 'action_dispatch/middleware/session/cookie_store'
|
||||
autoload :CookieStore, 'action_dispatch/middleware/session/cookie_store'
|
||||
autoload :MemCacheStore, 'action_dispatch/middleware/session/mem_cache_store'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -29,7 +29,7 @@ module ActionDispatch
|
|||
'ActionView::MissingTemplate' => 'missing_template',
|
||||
'ActionController::RoutingError' => 'routing_error',
|
||||
ActionController::UnknownAction.name => 'unknown_action',
|
||||
'ActionView::TemplateError' => 'template_error'
|
||||
'ActionView::Template::Error' => 'template_error'
|
||||
})
|
||||
|
||||
FAILSAFE_RESPONSE = [500, {'Content-Type' => 'text/html'},
|
||||
|
@ -119,7 +119,7 @@ module ActionDispatch
|
|||
return unless logger
|
||||
|
||||
ActiveSupport::Deprecation.silence do
|
||||
if ActionView::TemplateError === exception
|
||||
if ActionView::Template::Error === exception
|
||||
logger.fatal(exception.to_s)
|
||||
else
|
||||
logger.fatal(
|
||||
|
|
6
actionpack/lib/action_dispatch/test_case.rb
Normal file
6
actionpack/lib/action_dispatch/test_case.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
require "action_dispatch/testing/assertions"
|
||||
require "action_dispatch/testing/integration"
|
||||
require "action_dispatch/testing/performance_test"
|
||||
require "action_dispatch/testing/test_request"
|
||||
require "action_dispatch/testing/test_response"
|
||||
require "action_dispatch/testing/integration"
|
|
@ -24,27 +24,25 @@
|
|||
require File.join(File.dirname(__FILE__), "action_pack")
|
||||
|
||||
module ActionView
|
||||
def self.load_all!
|
||||
[Context, Base, TemplateError]
|
||||
extend ActiveSupport::Autoload
|
||||
|
||||
autoload :Base
|
||||
autoload :Context
|
||||
autoload :Template
|
||||
autoload :Helpers
|
||||
autoload :SafeBuffer
|
||||
|
||||
|
||||
autoload_under "render" do
|
||||
autoload :Partials
|
||||
autoload :Rendering
|
||||
end
|
||||
|
||||
autoload :Base, 'action_view/base'
|
||||
autoload :Context, 'action_view/context'
|
||||
autoload :Helpers, 'action_view/helpers'
|
||||
autoload :MissingTemplate, 'action_view/base'
|
||||
autoload :Partials, 'action_view/render/partials'
|
||||
autoload :Resolver, 'action_view/template/resolver'
|
||||
autoload :PathResolver, 'action_view/template/resolver'
|
||||
autoload :PathSet, 'action_view/paths'
|
||||
autoload :Rendering, 'action_view/render/rendering'
|
||||
autoload :Template, 'action_view/template/template'
|
||||
autoload :TemplateError, 'action_view/template/error'
|
||||
autoload :TemplateHandler, 'action_view/template/handler'
|
||||
autoload :TemplateHandlers, 'action_view/template/handlers'
|
||||
autoload :TextTemplate, 'action_view/template/text'
|
||||
autoload :Helpers, 'action_view/helpers'
|
||||
autoload :FileSystemResolverWithFallback, 'action_view/template/resolver'
|
||||
autoload :SafeBuffer, 'action_view/safe_buffer'
|
||||
end
|
||||
|
||||
require 'action_view/erb/util'
|
||||
|
|
|
@ -196,7 +196,7 @@ module ActionView #:nodoc:
|
|||
end
|
||||
|
||||
class << self
|
||||
delegate :erb_trim_mode=, :to => 'ActionView::TemplateHandlers::ERB'
|
||||
delegate :erb_trim_mode=, :to => 'ActionView::Template::Handlers::ERB'
|
||||
delegate :logger, :to => 'ActionController::Base', :allow_nil => true
|
||||
end
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ module ActionView #:nodoc:
|
|||
# TODO: Clean this up
|
||||
if obj.is_a?(String)
|
||||
if cache.nil?
|
||||
cache = !defined?(Rails) || Rails.application.config.cache_classes
|
||||
cache = !defined?(Rails.application) || Rails.application.config.cache_classes
|
||||
end
|
||||
FileSystemResolverWithFallback.new(obj, :cache => cache)
|
||||
else
|
||||
|
|
|
@ -6,7 +6,14 @@ require "action_view/template/resolver"
|
|||
|
||||
module ActionView
|
||||
class Template
|
||||
extend TemplateHandlers
|
||||
extend ActiveSupport::Autoload
|
||||
|
||||
autoload :Error
|
||||
autoload :Handler
|
||||
autoload :Handlers
|
||||
autoload :Text
|
||||
|
||||
extend Template::Handlers
|
||||
attr_reader :source, :identifier, :handler, :mime_type, :formats, :details
|
||||
|
||||
def initialize(source, identifier, handler, details)
|
||||
|
@ -32,11 +39,11 @@ module ActionView
|
|||
view.send(method_name, locals, &block)
|
||||
end
|
||||
rescue Exception => e
|
||||
if e.is_a?(TemplateError)
|
||||
if e.is_a?(Template::Error)
|
||||
e.sub_template_of(self)
|
||||
raise e
|
||||
else
|
||||
raise TemplateError.new(self, view.assigns, e)
|
||||
raise Template::Error.new(self, view.assigns, e)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -103,7 +110,7 @@ module ActionView
|
|||
logger.debug "Backtrace: #{e.backtrace.join("\n")}"
|
||||
end
|
||||
|
||||
raise ActionView::TemplateError.new(self, {}, e)
|
||||
raise ActionView::Template::Error.new(self, {}, e)
|
||||
end
|
||||
end
|
||||
|
|
@ -1,101 +1,103 @@
|
|||
require "active_support/core_ext/enumerable"
|
||||
|
||||
module ActionView
|
||||
# The TemplateError exception is raised when the compilation of the template fails. This exception then gathers a
|
||||
# bunch of intimate details and uses it to report a very precise exception message.
|
||||
class TemplateError < ActionViewError #:nodoc:
|
||||
SOURCE_CODE_RADIUS = 3
|
||||
class Template
|
||||
# The Template::Error exception is raised when the compilation of the template fails. This exception then gathers a
|
||||
# bunch of intimate details and uses it to report a very precise exception message.
|
||||
class Error < ActionViewError #:nodoc:
|
||||
SOURCE_CODE_RADIUS = 3
|
||||
|
||||
attr_reader :original_exception
|
||||
attr_reader :original_exception
|
||||
|
||||
def initialize(template, assigns, original_exception)
|
||||
@template, @assigns, @original_exception = template, assigns.dup, original_exception
|
||||
@backtrace = compute_backtrace
|
||||
end
|
||||
|
||||
def file_name
|
||||
@template.identifier
|
||||
end
|
||||
|
||||
def message
|
||||
ActiveSupport::Deprecation.silence { original_exception.message }
|
||||
end
|
||||
|
||||
def clean_backtrace
|
||||
if defined?(Rails) && Rails.respond_to?(:backtrace_cleaner)
|
||||
Rails.backtrace_cleaner.clean(original_exception.backtrace)
|
||||
else
|
||||
original_exception.backtrace
|
||||
def initialize(template, assigns, original_exception)
|
||||
@template, @assigns, @original_exception = template, assigns.dup, original_exception
|
||||
@backtrace = compute_backtrace
|
||||
end
|
||||
end
|
||||
|
||||
def sub_template_message
|
||||
if @sub_templates
|
||||
"Trace of template inclusion: " +
|
||||
@sub_templates.collect { |template| template.inspect }.join(", ")
|
||||
else
|
||||
""
|
||||
def file_name
|
||||
@template.identifier
|
||||
end
|
||||
end
|
||||
|
||||
def source_extract(indentation = 0)
|
||||
return unless num = line_number
|
||||
num = num.to_i
|
||||
|
||||
source_code = @template.source.split("\n")
|
||||
|
||||
start_on_line = [ num - SOURCE_CODE_RADIUS - 1, 0 ].max
|
||||
end_on_line = [ num + SOURCE_CODE_RADIUS - 1, source_code.length].min
|
||||
|
||||
indent = ' ' * indentation
|
||||
line_counter = start_on_line
|
||||
return unless source_code = source_code[start_on_line..end_on_line]
|
||||
|
||||
source_code.sum do |line|
|
||||
line_counter += 1
|
||||
"#{indent}#{line_counter}: #{line}\n"
|
||||
def message
|
||||
ActiveSupport::Deprecation.silence { original_exception.message }
|
||||
end
|
||||
end
|
||||
|
||||
def sub_template_of(template_path)
|
||||
@sub_templates ||= []
|
||||
@sub_templates << template_path
|
||||
end
|
||||
def clean_backtrace
|
||||
if defined?(Rails) && Rails.respond_to?(:backtrace_cleaner)
|
||||
Rails.backtrace_cleaner.clean(original_exception.backtrace)
|
||||
else
|
||||
original_exception.backtrace
|
||||
end
|
||||
end
|
||||
|
||||
def line_number
|
||||
@line_number ||=
|
||||
if file_name
|
||||
regexp = /#{Regexp.escape File.basename(file_name)}:(\d+)/
|
||||
def sub_template_message
|
||||
if @sub_templates
|
||||
"Trace of template inclusion: " +
|
||||
@sub_templates.collect { |template| template.inspect }.join(", ")
|
||||
else
|
||||
""
|
||||
end
|
||||
end
|
||||
|
||||
$1 if message =~ regexp or clean_backtrace.find { |line| line =~ regexp }
|
||||
def source_extract(indentation = 0)
|
||||
return unless num = line_number
|
||||
num = num.to_i
|
||||
|
||||
source_code = @template.source.split("\n")
|
||||
|
||||
start_on_line = [ num - SOURCE_CODE_RADIUS - 1, 0 ].max
|
||||
end_on_line = [ num + SOURCE_CODE_RADIUS - 1, source_code.length].min
|
||||
|
||||
indent = ' ' * indentation
|
||||
line_counter = start_on_line
|
||||
return unless source_code = source_code[start_on_line..end_on_line]
|
||||
|
||||
source_code.sum do |line|
|
||||
line_counter += 1
|
||||
"#{indent}#{line_counter}: #{line}\n"
|
||||
end
|
||||
end
|
||||
|
||||
def sub_template_of(template_path)
|
||||
@sub_templates ||= []
|
||||
@sub_templates << template_path
|
||||
end
|
||||
|
||||
def line_number
|
||||
@line_number ||=
|
||||
if file_name
|
||||
regexp = /#{Regexp.escape File.basename(file_name)}:(\d+)/
|
||||
|
||||
$1 if message =~ regexp or clean_backtrace.find { |line| line =~ regexp }
|
||||
end
|
||||
end
|
||||
|
||||
def to_s
|
||||
"\n#{self.class} (#{message}) #{source_location}:\n" +
|
||||
"#{source_extract}\n #{clean_backtrace.join("\n ")}\n\n"
|
||||
end
|
||||
|
||||
# don't do anything nontrivial here. Any raised exception from here becomes fatal
|
||||
# (and can't be rescued).
|
||||
def backtrace
|
||||
@backtrace
|
||||
end
|
||||
|
||||
private
|
||||
def compute_backtrace
|
||||
[
|
||||
"#{source_location.capitalize}\n\n#{source_extract(4)}\n " +
|
||||
clean_backtrace.join("\n ")
|
||||
]
|
||||
end
|
||||
|
||||
def source_location
|
||||
if line_number
|
||||
"on line ##{line_number} of "
|
||||
else
|
||||
'in '
|
||||
end + file_name
|
||||
end
|
||||
end
|
||||
|
||||
def to_s
|
||||
"\n#{self.class} (#{message}) #{source_location}:\n" +
|
||||
"#{source_extract}\n #{clean_backtrace.join("\n ")}\n\n"
|
||||
end
|
||||
|
||||
# don't do anything nontrivial here. Any raised exception from here becomes fatal
|
||||
# (and can't be rescued).
|
||||
def backtrace
|
||||
@backtrace
|
||||
end
|
||||
|
||||
private
|
||||
def compute_backtrace
|
||||
[
|
||||
"#{source_location.capitalize}\n\n#{source_extract(4)}\n " +
|
||||
clean_backtrace.join("\n ")
|
||||
]
|
||||
end
|
||||
|
||||
def source_location
|
||||
if line_number
|
||||
"on line ##{line_number} of "
|
||||
else
|
||||
'in '
|
||||
end + file_name
|
||||
end
|
||||
end
|
||||
end
|
|
@ -3,34 +3,39 @@ require "action_dispatch/http/mime_type"
|
|||
|
||||
# Legacy TemplateHandler stub
|
||||
module ActionView
|
||||
module TemplateHandlers #:nodoc:
|
||||
module Compilable
|
||||
def self.included(base)
|
||||
base.extend(ClassMethods)
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
def call(template)
|
||||
new.compile(template)
|
||||
class Template
|
||||
module Handlers #:nodoc:
|
||||
module Compilable
|
||||
def self.included(base)
|
||||
base.extend(ClassMethods)
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
def call(template)
|
||||
new.compile(template)
|
||||
end
|
||||
end
|
||||
|
||||
def compile(template)
|
||||
raise "Need to implement #{self.class.name}#compile(template)"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Template::Handler
|
||||
extlib_inheritable_accessor :default_format
|
||||
self.default_format = Mime::HTML
|
||||
|
||||
def self.call(template)
|
||||
raise "Need to implement #{self.class.name}#call(template)"
|
||||
end
|
||||
|
||||
def compile(template)
|
||||
raise "Need to implement #{self.class.name}#compile(template)"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class TemplateHandler
|
||||
extlib_inheritable_accessor :default_format
|
||||
self.default_format = Mime::HTML
|
||||
|
||||
def self.call(template)
|
||||
raise "Need to implement #{self.class.name}#call(template)"
|
||||
end
|
||||
|
||||
def render(template, local_assigns)
|
||||
raise "Need to implement #{self.class.name}#render(template, local_assigns)"
|
||||
def render(template, local_assigns)
|
||||
raise "Need to implement #{self.class.name}#render(template, local_assigns)"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
TemplateHandlers = Template::Handlers
|
||||
TemplateHandler = Template::Handler
|
||||
end
|
||||
|
|
|
@ -1,52 +1,54 @@
|
|||
module ActionView #:nodoc:
|
||||
module TemplateHandlers #:nodoc:
|
||||
autoload :ERB, 'action_view/template/handlers/erb'
|
||||
autoload :RJS, 'action_view/template/handlers/rjs'
|
||||
autoload :Builder, 'action_view/template/handlers/builder'
|
||||
class Template
|
||||
module Handlers #:nodoc:
|
||||
autoload :ERB, 'action_view/template/handlers/erb'
|
||||
autoload :RJS, 'action_view/template/handlers/rjs'
|
||||
autoload :Builder, 'action_view/template/handlers/builder'
|
||||
|
||||
def self.extended(base)
|
||||
base.register_default_template_handler :erb, TemplateHandlers::ERB
|
||||
base.register_template_handler :rjs, TemplateHandlers::RJS
|
||||
base.register_template_handler :builder, TemplateHandlers::Builder
|
||||
def self.extended(base)
|
||||
base.register_default_template_handler :erb, ERB
|
||||
base.register_template_handler :rjs, RJS
|
||||
base.register_template_handler :builder, Builder
|
||||
|
||||
# TODO: Depreciate old template extensions
|
||||
base.register_template_handler :rhtml, TemplateHandlers::ERB
|
||||
base.register_template_handler :rxml, TemplateHandlers::Builder
|
||||
end
|
||||
# TODO: Depreciate old template extensions
|
||||
base.register_template_handler :rhtml, ERB
|
||||
base.register_template_handler :rxml, Builder
|
||||
end
|
||||
|
||||
@@template_handlers = {}
|
||||
@@default_template_handlers = nil
|
||||
@@template_handlers = {}
|
||||
@@default_template_handlers = nil
|
||||
|
||||
def self.extensions
|
||||
@@template_handlers.keys
|
||||
end
|
||||
def self.extensions
|
||||
@@template_handlers.keys
|
||||
end
|
||||
|
||||
# Register a class that knows how to handle template files with the given
|
||||
# extension. This can be used to implement new template types.
|
||||
# The constructor for the class must take the ActiveView::Base instance
|
||||
# as a parameter, and the class must implement a +render+ method that
|
||||
# takes the contents of the template to render as well as the Hash of
|
||||
# local assigns available to the template. The +render+ method ought to
|
||||
# return the rendered template as a string.
|
||||
def register_template_handler(extension, klass)
|
||||
@@template_handlers[extension.to_sym] = klass
|
||||
end
|
||||
# Register a class that knows how to handle template files with the given
|
||||
# extension. This can be used to implement new template types.
|
||||
# The constructor for the class must take the ActiveView::Base instance
|
||||
# as a parameter, and the class must implement a +render+ method that
|
||||
# takes the contents of the template to render as well as the Hash of
|
||||
# local assigns available to the template. The +render+ method ought to
|
||||
# return the rendered template as a string.
|
||||
def register_template_handler(extension, klass)
|
||||
@@template_handlers[extension.to_sym] = klass
|
||||
end
|
||||
|
||||
def template_handler_extensions
|
||||
@@template_handlers.keys.map {|key| key.to_s }.sort
|
||||
end
|
||||
def template_handler_extensions
|
||||
@@template_handlers.keys.map {|key| key.to_s }.sort
|
||||
end
|
||||
|
||||
def registered_template_handler(extension)
|
||||
extension && @@template_handlers[extension.to_sym]
|
||||
end
|
||||
def registered_template_handler(extension)
|
||||
extension && @@template_handlers[extension.to_sym]
|
||||
end
|
||||
|
||||
def register_default_template_handler(extension, klass)
|
||||
register_template_handler(extension, klass)
|
||||
@@default_template_handlers = klass
|
||||
end
|
||||
def register_default_template_handler(extension, klass)
|
||||
register_template_handler(extension, klass)
|
||||
@@default_template_handlers = klass
|
||||
end
|
||||
|
||||
def handler_class_for_extension(extension)
|
||||
(extension && registered_template_handler(extension.to_sym)) || @@default_template_handlers
|
||||
def handler_class_for_extension(extension)
|
||||
(extension && registered_template_handler(extension.to_sym)) || @@default_template_handlers
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
module ActionView
|
||||
module TemplateHandlers
|
||||
class Builder < TemplateHandler
|
||||
module Template::Handlers
|
||||
class Builder < Template::Handler
|
||||
include Compilable
|
||||
|
||||
self.default_format = Mime::XML
|
||||
|
|
|
@ -3,7 +3,7 @@ require 'active_support/core_ext/string/output_safety'
|
|||
require 'erubis'
|
||||
|
||||
module ActionView
|
||||
module TemplateHandlers
|
||||
module Template::Handlers
|
||||
class Erubis < ::Erubis::Eruby
|
||||
def add_preamble(src)
|
||||
src << "@output_buffer = ActionView::SafeBuffer.new;"
|
||||
|
@ -26,7 +26,7 @@ module ActionView
|
|||
end
|
||||
end
|
||||
|
||||
class ERB < TemplateHandler
|
||||
class ERB < Template::Handler
|
||||
include Compilable
|
||||
|
||||
##
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
module ActionView
|
||||
module TemplateHandlers
|
||||
class RJS < TemplateHandler
|
||||
module Template::Handlers
|
||||
class RJS < Template::Handler
|
||||
include Compilable
|
||||
|
||||
self.default_format = Mime::JS
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
require "pathname"
|
||||
require "active_support/core_ext/class"
|
||||
require "action_view/template/template"
|
||||
require "action_view/template"
|
||||
|
||||
module ActionView
|
||||
# Abstract superclass
|
||||
|
@ -20,7 +20,7 @@ module ActionView
|
|||
register_detail(:locale) { [I18n.locale] }
|
||||
register_detail(:formats) { Mime::SET.symbols }
|
||||
register_detail(:handlers, :allow_nil => false) do
|
||||
TemplateHandlers.extensions
|
||||
Template::Handlers.extensions
|
||||
end
|
||||
|
||||
def initialize(options = {})
|
||||
|
@ -65,7 +65,7 @@ module ActionView
|
|||
# as well as incorrectly putting part of the path in the template
|
||||
# name instead of the prefix.
|
||||
def normalize_name(name, prefix)
|
||||
handlers = TemplateHandlers.extensions.join('|')
|
||||
handlers = Template::Handlers.extensions.join('|')
|
||||
name = name.to_s.gsub(/\.(?:#{handlers})$/, '')
|
||||
|
||||
parts = name.split('/')
|
||||
|
|
|
@ -1,38 +1,40 @@
|
|||
module ActionView #:nodoc:
|
||||
class TextTemplate < String #:nodoc:
|
||||
HTML = Mime[:html]
|
||||
class Template
|
||||
class Text < String #:nodoc:
|
||||
HTML = Mime[:html]
|
||||
|
||||
def initialize(string, content_type = HTML)
|
||||
super(string.to_s)
|
||||
@content_type = Mime[content_type] || content_type
|
||||
end
|
||||
def initialize(string, content_type = HTML)
|
||||
super(string.to_s)
|
||||
@content_type = Mime[content_type] || content_type
|
||||
end
|
||||
|
||||
def details
|
||||
{:formats => [@content_type.to_sym]}
|
||||
end
|
||||
def details
|
||||
{:formats => [@content_type.to_sym]}
|
||||
end
|
||||
|
||||
def identifier
|
||||
self
|
||||
end
|
||||
def identifier
|
||||
self
|
||||
end
|
||||
|
||||
def inspect
|
||||
'text template'
|
||||
end
|
||||
def inspect
|
||||
'text template'
|
||||
end
|
||||
|
||||
def render(*args)
|
||||
to_s
|
||||
end
|
||||
def render(*args)
|
||||
to_s
|
||||
end
|
||||
|
||||
def mime_type
|
||||
@content_type
|
||||
end
|
||||
def mime_type
|
||||
@content_type
|
||||
end
|
||||
|
||||
def formats
|
||||
[mime_type]
|
||||
end
|
||||
def formats
|
||||
[mime_type]
|
||||
end
|
||||
|
||||
def partial?
|
||||
false
|
||||
def partial?
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
require 'active_support/test_case'
|
||||
require 'action_controller/testing/test_case'
|
||||
require 'action_controller/test_case'
|
||||
|
||||
module ActionView
|
||||
class Base
|
||||
|
|
|
@ -23,7 +23,7 @@ module AbstractControllerTests
|
|||
self.view_paths = []
|
||||
|
||||
def index
|
||||
render :_template => ActionView::TextTemplate.new("Hello blank!")
|
||||
render :_template => ActionView::Template::Text.new("Hello blank!")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -31,19 +31,19 @@ module AbstractControllerTests
|
|||
layout "hello"
|
||||
|
||||
def index
|
||||
render :_template => ActionView::TextTemplate.new("Hello string!")
|
||||
render :_template => ActionView::Template::Text.new("Hello string!")
|
||||
end
|
||||
|
||||
def overwrite_default
|
||||
render :_template => ActionView::TextTemplate.new("Hello string!"), :layout => :default
|
||||
render :_template => ActionView::Template::Text.new("Hello string!"), :layout => :default
|
||||
end
|
||||
|
||||
def overwrite_false
|
||||
render :_template => ActionView::TextTemplate.new("Hello string!"), :layout => false
|
||||
render :_template => ActionView::Template::Text.new("Hello string!"), :layout => false
|
||||
end
|
||||
|
||||
def overwrite_string
|
||||
render :_template => ActionView::TextTemplate.new("Hello string!"), :layout => "omg"
|
||||
render :_template => ActionView::Template::Text.new("Hello string!"), :layout => "omg"
|
||||
end
|
||||
|
||||
def overwrite_skip
|
||||
|
@ -72,7 +72,7 @@ module AbstractControllerTests
|
|||
layout :hello
|
||||
|
||||
def index
|
||||
render :_template => ActionView::TextTemplate.new("Hello symbol!")
|
||||
render :_template => ActionView::Template::Text.new("Hello symbol!")
|
||||
end
|
||||
private
|
||||
def hello
|
||||
|
@ -84,7 +84,7 @@ module AbstractControllerTests
|
|||
layout :no_hello
|
||||
|
||||
def index
|
||||
render :_template => ActionView::TextTemplate.new("Hello missing symbol!")
|
||||
render :_template => ActionView::Template::Text.new("Hello missing symbol!")
|
||||
end
|
||||
private
|
||||
def no_hello
|
||||
|
@ -96,7 +96,7 @@ module AbstractControllerTests
|
|||
layout :nilz
|
||||
|
||||
def index
|
||||
render :_template => ActionView::TextTemplate.new("Hello nilz!")
|
||||
render :_template => ActionView::Template::Text.new("Hello nilz!")
|
||||
end
|
||||
|
||||
def nilz() end
|
||||
|
@ -106,7 +106,7 @@ module AbstractControllerTests
|
|||
layout :objekt
|
||||
|
||||
def index
|
||||
render :_template => ActionView::TextTemplate.new("Hello nilz!")
|
||||
render :_template => ActionView::Template::Text.new("Hello nilz!")
|
||||
end
|
||||
|
||||
def objekt
|
||||
|
@ -118,7 +118,7 @@ module AbstractControllerTests
|
|||
layout :omg_no_method
|
||||
|
||||
def index
|
||||
render :_template => ActionView::TextTemplate.new("Hello boom!")
|
||||
render :_template => ActionView::Template::Text.new("Hello boom!")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -126,7 +126,7 @@ module AbstractControllerTests
|
|||
layout "missing"
|
||||
|
||||
def index
|
||||
render :_template => ActionView::TextTemplate.new("Hello missing!")
|
||||
render :_template => ActionView::Template::Text.new("Hello missing!")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -134,7 +134,7 @@ module AbstractControllerTests
|
|||
layout false
|
||||
|
||||
def index
|
||||
render :_template => ActionView::TextTemplate.new("Hello false!")
|
||||
render :_template => ActionView::Template::Text.new("Hello false!")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -142,7 +142,7 @@ module AbstractControllerTests
|
|||
layout nil
|
||||
|
||||
def index
|
||||
render :_template => ActionView::TextTemplate.new("Hello nil!")
|
||||
render :_template => ActionView::Template::Text.new("Hello nil!")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ module AbstractController
|
|||
end
|
||||
|
||||
def object
|
||||
render :_template => ActionView::TextTemplate.new("With Object")
|
||||
render :_template => ActionView::Template::Text.new("With Object")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -191,7 +191,7 @@ class IsolatedHelpersTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_helper_in_a
|
||||
assert_raise(ActionView::TemplateError) { call_controller(A, "index") }
|
||||
assert_raise(ActionView::Template::Error) { call_controller(A, "index") }
|
||||
end
|
||||
|
||||
def test_helper_in_b
|
||||
|
|
|
@ -115,7 +115,7 @@ class RendersNoLayoutController < LayoutTest
|
|||
end
|
||||
|
||||
class LayoutSetInResponseTest < ActionController::TestCase
|
||||
include ActionView::TemplateHandlers
|
||||
include ActionView::Template::Handlers
|
||||
|
||||
def test_layout_set_when_using_default_layout
|
||||
@controller = DefaultLayoutController.new
|
||||
|
|
|
@ -106,8 +106,8 @@ module RenderTestCases
|
|||
|
||||
def test_render_partial_with_errors
|
||||
@view.render(:partial => "test/raise")
|
||||
flunk "Render did not raise TemplateError"
|
||||
rescue ActionView::TemplateError => e
|
||||
flunk "Render did not raise Template::Error"
|
||||
rescue ActionView::Template::Error => e
|
||||
assert_match "undefined local variable or method `doesnt_exist'", e.message
|
||||
assert_equal "", e.sub_template_message
|
||||
assert_equal "1", e.line_number
|
||||
|
@ -116,8 +116,8 @@ module RenderTestCases
|
|||
|
||||
def test_render_sub_template_with_errors
|
||||
@view.render(:file => "test/sub_template_raise")
|
||||
flunk "Render did not raise TemplateError"
|
||||
rescue ActionView::TemplateError => e
|
||||
flunk "Render did not raise Template::Error"
|
||||
rescue ActionView::Template::Error => e
|
||||
assert_match "undefined local variable or method `doesnt_exist'", e.message
|
||||
assert_equal "Trace of template inclusion: #{File.expand_path("#{FIXTURE_LOAD_PATH}/test/sub_template_raise.html.erb")}", e.sub_template_message
|
||||
assert_equal "1", e.line_number
|
||||
|
|
|
@ -26,28 +26,31 @@ $:.unshift(activesupport_path) if File.directory?(activesupport_path)
|
|||
require 'active_support'
|
||||
|
||||
module ActiveModel
|
||||
autoload :AttributeMethods, 'active_model/attribute_methods'
|
||||
autoload :Conversion, 'active_model/conversion'
|
||||
autoload :DeprecatedErrorMethods, 'active_model/deprecated_error_methods'
|
||||
autoload :Dirty, 'active_model/dirty'
|
||||
autoload :Errors, 'active_model/errors'
|
||||
autoload :Lint, 'active_model/lint'
|
||||
autoload :Name, 'active_model/naming'
|
||||
autoload :Naming, 'active_model/naming'
|
||||
autoload :Observer, 'active_model/observing'
|
||||
autoload :Observing, 'active_model/observing'
|
||||
autoload :Serialization, 'active_model/serialization'
|
||||
autoload :StateMachine, 'active_model/state_machine'
|
||||
autoload :TestCase, 'active_model/test_case'
|
||||
autoload :Translation, 'active_model/translation'
|
||||
autoload :Validations, 'active_model/validations'
|
||||
autoload :ValidationsRepairHelper, 'active_model/validations_repair_helper'
|
||||
autoload :Validator, 'active_model/validator'
|
||||
autoload :VERSION, 'active_model/version'
|
||||
extend ActiveSupport::Autoload
|
||||
|
||||
autoload :AttributeMethods
|
||||
autoload :Conversion
|
||||
autoload :DeprecatedErrorMethods
|
||||
autoload :Dirty
|
||||
autoload :Errors
|
||||
autoload :Lint
|
||||
autoload :Name, 'active_model/naming'
|
||||
autoload :Naming
|
||||
autoload :Observer, 'active_model/observing'
|
||||
autoload :Observing
|
||||
autoload :Serialization
|
||||
autoload :StateMachine
|
||||
autoload :Translation
|
||||
autoload :Validations
|
||||
autoload :ValidationsRepairHelper
|
||||
autoload :Validator
|
||||
autoload :VERSION
|
||||
|
||||
module Serializers
|
||||
autoload :JSON, 'active_model/serializers/json'
|
||||
autoload :Xml, 'active_model/serializers/xml'
|
||||
extend ActiveSupport::Autoload
|
||||
|
||||
autoload :JSON
|
||||
autoload :Xml
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ $:.unshift(lib) unless $:.include?('lib') || $:.include?(lib)
|
|||
|
||||
require 'config'
|
||||
require 'active_model'
|
||||
require 'active_model/test_case'
|
||||
|
||||
# Show backtraces for deprecated behavior for quicker cleanup.
|
||||
ActiveSupport::Deprecation.debug = true
|
||||
|
|
|
@ -2,6 +2,7 @@ require 'logger'
|
|||
|
||||
$:.unshift(File.dirname(__FILE__) + '/../../../activerecord/lib')
|
||||
require 'active_record'
|
||||
require 'active_record/test_case'
|
||||
require 'active_record/fixtures'
|
||||
|
||||
module ActiveModel
|
||||
|
|
|
@ -32,64 +32,66 @@ require 'active_model'
|
|||
require 'arel'
|
||||
|
||||
module ActiveRecord
|
||||
# TODO: Review explicit loads to see if they will automatically be handled by the initializer.
|
||||
def self.load_all!
|
||||
[Base, DynamicFinderMatch, ConnectionAdapters::AbstractAdapter]
|
||||
end
|
||||
extend ActiveSupport::Autoload
|
||||
|
||||
autoload :VERSION, 'active_record/version'
|
||||
autoload :VERSION
|
||||
|
||||
autoload :ActiveRecordError, 'active_record/base'
|
||||
autoload :ConnectionNotEstablished, 'active_record/base'
|
||||
|
||||
autoload :Aggregations, 'active_record/aggregations'
|
||||
autoload :AssociationPreload, 'active_record/association_preload'
|
||||
autoload :Associations, 'active_record/associations'
|
||||
autoload :AttributeMethods, 'active_record/attribute_methods'
|
||||
autoload :Attributes, 'active_record/attributes'
|
||||
autoload :AutosaveAssociation, 'active_record/autosave_association'
|
||||
autoload :Relation, 'active_record/relation'
|
||||
autoload :Base, 'active_record/base'
|
||||
autoload :Batches, 'active_record/batches'
|
||||
autoload :Calculations, 'active_record/calculations'
|
||||
autoload :Callbacks, 'active_record/callbacks'
|
||||
autoload :DynamicFinderMatch, 'active_record/dynamic_finder_match'
|
||||
autoload :DynamicScopeMatch, 'active_record/dynamic_scope_match'
|
||||
autoload :Migration, 'active_record/migration'
|
||||
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, 'active_record/named_scope'
|
||||
autoload :NestedAttributes, 'active_record/nested_attributes'
|
||||
autoload :Observer, 'active_record/observer'
|
||||
autoload :QueryCache, 'active_record/query_cache'
|
||||
autoload :Reflection, 'active_record/reflection'
|
||||
autoload :Schema, 'active_record/schema'
|
||||
autoload :SchemaDumper, 'active_record/schema_dumper'
|
||||
autoload :Serialization, 'active_record/serialization'
|
||||
autoload :SessionStore, 'active_record/session_store'
|
||||
autoload :StateMachine, 'active_record/state_machine'
|
||||
autoload :TestCase, 'active_record/test_case'
|
||||
autoload :Timestamp, 'active_record/timestamp'
|
||||
autoload :Transactions, 'active_record/transactions'
|
||||
autoload :Types, 'active_record/types'
|
||||
autoload :Validations, 'active_record/validations'
|
||||
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
|
||||
|
||||
module AttributeMethods
|
||||
autoload :BeforeTypeCast, 'active_record/attribute_methods/before_type_cast'
|
||||
autoload :Dirty, 'active_record/attribute_methods/dirty'
|
||||
autoload :PrimaryKey, 'active_record/attribute_methods/primary_key'
|
||||
autoload :Query, 'active_record/attribute_methods/query'
|
||||
autoload :Read, 'active_record/attribute_methods/read'
|
||||
autoload :TimeZoneConversion, 'active_record/attribute_methods/time_zone_conversion'
|
||||
autoload :Write, 'active_record/attribute_methods/write'
|
||||
extend ActiveSupport::Autoload
|
||||
|
||||
autoload :BeforeTypeCast
|
||||
autoload :Dirty
|
||||
autoload :PrimaryKey
|
||||
autoload :Query
|
||||
autoload :Read
|
||||
autoload :TimeZoneConversion
|
||||
autoload :Write
|
||||
end
|
||||
|
||||
module Attributes
|
||||
autoload :Aliasing, 'active_record/attributes/aliasing'
|
||||
autoload :Store, 'active_record/attributes/store'
|
||||
autoload :Typecasting, 'active_record/attributes/typecasting'
|
||||
extend ActiveSupport::Autoload
|
||||
|
||||
autoload :Aliasing
|
||||
autoload :Store
|
||||
autoload :Typecasting
|
||||
end
|
||||
|
||||
module Type
|
||||
extend ActiveSupport::Autoload
|
||||
|
||||
autoload :Number, 'active_record/types/number'
|
||||
autoload :Object, 'active_record/types/object'
|
||||
autoload :Serialize, 'active_record/types/serialize'
|
||||
|
@ -98,12 +100,16 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
module Locking
|
||||
autoload :Optimistic, 'active_record/locking/optimistic'
|
||||
autoload :Pessimistic, 'active_record/locking/pessimistic'
|
||||
extend ActiveSupport::Autoload
|
||||
|
||||
autoload :Optimistic
|
||||
autoload :Pessimistic
|
||||
end
|
||||
|
||||
module ConnectionAdapters
|
||||
autoload :AbstractAdapter, 'active_record/connection_adapters/abstract_adapter'
|
||||
extend ActiveSupport::Autoload
|
||||
|
||||
autoload :AbstractAdapter
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -30,11 +30,13 @@ $:.unshift(activemodel_path) if File.directory?(activemodel_path)
|
|||
require 'active_model'
|
||||
|
||||
module ActiveResource
|
||||
autoload :Base, 'active_resource/base'
|
||||
autoload :Connection, 'active_resource/connection'
|
||||
autoload :CustomMethods, 'active_resource/custom_methods'
|
||||
autoload :Formats, 'active_resource/formats'
|
||||
autoload :Observing, 'active_resource/observing'
|
||||
autoload :Validations, 'active_resource/validations'
|
||||
autoload :HttpMock, 'active_resource/http_mock'
|
||||
extend ActiveSupport::Autoload
|
||||
|
||||
autoload :Base
|
||||
autoload :Connection
|
||||
autoload :CustomMethods
|
||||
autoload :Formats
|
||||
autoload :Observing
|
||||
autoload :Validations
|
||||
autoload :HttpMock
|
||||
end
|
||||
|
|
|
@ -13,6 +13,7 @@ require 'test/unit'
|
|||
require 'active_support'
|
||||
require 'active_support/test_case'
|
||||
require 'active_resource'
|
||||
require 'active_model/test_case'
|
||||
|
||||
$:.unshift "#{File.dirname(__FILE__)}/../test"
|
||||
require 'setter_trap'
|
||||
|
|
|
@ -543,9 +543,9 @@ class BaseTest < Test::Unit::TestCase
|
|||
assert Person.collection_path(:gender => 'male', :student => true).include?('gender=male')
|
||||
assert Person.collection_path(:gender => 'male', :student => true).include?('student=true')
|
||||
|
||||
assert_equal '/people.xml?name%5B%5D=bob&name%5B%5D=your+uncle%2Bme&name%5B%5D=&name%5B%5D=false', Person.collection_path(:name => ['bob', 'your uncle+me', nil, false])
|
||||
assert_equal '/people.xml?name[]=bob&name[]=your+uncle%2Bme&name[]=&name[]=false', Person.collection_path(:name => ['bob', 'your uncle+me', nil, false])
|
||||
|
||||
assert_equal '/people.xml?struct%5Ba%5D%5B%5D=2&struct%5Ba%5D%5B%5D=1&struct%5Bb%5D=fred', Person.collection_path(:struct => {:a => [2,1], 'b' => 'fred'})
|
||||
assert_equal '/people.xml?struct[a][]=2&struct[a][]=1&struct[b]=fred', Person.collection_path(:struct => {:a => [2,1], 'b' => 'fred'})
|
||||
end
|
||||
|
||||
def test_custom_element_path
|
||||
|
@ -581,7 +581,7 @@ class BaseTest < Test::Unit::TestCase
|
|||
assert_equal '/people/1/addresses/1.xml?type=work', StreetAddress.element_path(1, :person_id => 1, :type => 'work')
|
||||
assert_equal '/people/1/addresses/1.xml?type=work', StreetAddress.element_path(1, 'person_id' => 1, :type => 'work')
|
||||
assert_equal '/people/1/addresses/1.xml?type=work', StreetAddress.element_path(1, :type => 'work', :person_id => 1)
|
||||
assert_equal '/people/1/addresses/1.xml?type%5B%5D=work&type%5B%5D=play+time', StreetAddress.element_path(1, :person_id => 1, :type => ['work', 'play time'])
|
||||
assert_equal '/people/1/addresses/1.xml?type[]=work&type[]=play+time', StreetAddress.element_path(1, :person_id => 1, :type => ['work', 'play time'])
|
||||
end
|
||||
|
||||
def test_custom_element_path_with_prefix_and_parameters
|
||||
|
|
|
@ -1,28 +1,31 @@
|
|||
require "active_support/dependencies/autoload"
|
||||
|
||||
module ActiveSupport
|
||||
autoload :BacktraceCleaner, 'active_support/backtrace_cleaner'
|
||||
autoload :Base64, 'active_support/base64'
|
||||
autoload :BasicObject, 'active_support/basic_object'
|
||||
autoload :Benchmarkable, 'active_support/benchmarkable'
|
||||
autoload :BufferedLogger, 'active_support/buffered_logger'
|
||||
autoload :Cache, 'active_support/cache'
|
||||
autoload :Callbacks, 'active_support/callbacks'
|
||||
autoload :Concern, 'active_support/concern'
|
||||
autoload :Configurable, 'active_support/configurable'
|
||||
autoload :DependencyModule, 'active_support/dependency_module'
|
||||
autoload :DeprecatedCallbacks, 'active_support/deprecated_callbacks'
|
||||
autoload :Deprecation, 'active_support/deprecation'
|
||||
autoload :Gzip, 'active_support/gzip'
|
||||
autoload :Inflector, 'active_support/inflector'
|
||||
autoload :Memoizable, 'active_support/memoizable'
|
||||
autoload :MessageEncryptor, 'active_support/message_encryptor'
|
||||
autoload :MessageVerifier, 'active_support/message_verifier'
|
||||
autoload :Multibyte, 'active_support/multibyte'
|
||||
autoload :OptionMerger, 'active_support/option_merger'
|
||||
autoload :OrderedHash, 'active_support/ordered_hash'
|
||||
autoload :OrderedOptions, 'active_support/ordered_options'
|
||||
autoload :Notifications, 'active_support/notifications'
|
||||
autoload :Rescuable, 'active_support/rescuable'
|
||||
autoload :SecureRandom, 'active_support/secure_random'
|
||||
autoload :StringInquirer, 'active_support/string_inquirer'
|
||||
autoload :XmlMini, 'active_support/xml_mini'
|
||||
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
|
||||
end
|
||||
|
|
37
activesupport/lib/active_support/dependencies/autoload.rb
Normal file
37
activesupport/lib/active_support/dependencies/autoload.rb
Normal file
|
@ -0,0 +1,37 @@
|
|||
require "active_support/inflector/methods"
|
||||
|
||||
module ActiveSupport
|
||||
module Autoload
|
||||
|
||||
@@autoloads = {}
|
||||
@@under_path = nil
|
||||
@@at_path = nil
|
||||
|
||||
def autoload(const_name, path = @@at_path)
|
||||
full = [self.name, @@under_path, const_name.to_s, path].compact.join("::")
|
||||
location = path || Inflector.underscore(full)
|
||||
|
||||
@@autoloads[const_name] = location
|
||||
super const_name, location
|
||||
end
|
||||
|
||||
def autoload_under(path)
|
||||
@@under_path, old_path = path, @@under_path
|
||||
yield
|
||||
ensure
|
||||
@@under_path = old_path
|
||||
end
|
||||
|
||||
def autoload_at(path)
|
||||
@@at_path, old_path = path, @@at_path
|
||||
yield
|
||||
ensure
|
||||
@@at_path = old_path
|
||||
end
|
||||
|
||||
def self.eager_autoload!
|
||||
@@autoloads.values.each {|file| require file }
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -1,450 +1,454 @@
|
|||
require 'ruby-prof'
|
||||
begin
|
||||
require 'ruby-prof'
|
||||
|
||||
require 'fileutils'
|
||||
require 'rails/version'
|
||||
require 'fileutils'
|
||||
require 'rails/version'
|
||||
require 'active_support/core_ext/class/delegating_attributes'
|
||||
|
||||
module ActiveSupport
|
||||
module Testing
|
||||
module Performance
|
||||
DEFAULTS =
|
||||
if benchmark = ARGV.include?('--benchmark') # HAX for rake test
|
||||
{ :benchmark => true,
|
||||
:runs => 4,
|
||||
:metrics => [:wall_time, :memory, :objects, :gc_runs, :gc_time],
|
||||
:output => 'tmp/performance' }
|
||||
else
|
||||
{ :benchmark => false,
|
||||
:runs => 1,
|
||||
:min_percent => 0.01,
|
||||
:metrics => [:process_time, :memory, :objects],
|
||||
:formats => [:flat, :graph_html, :call_tree],
|
||||
:output => 'tmp/performance' }
|
||||
end.freeze
|
||||
module ActiveSupport
|
||||
module Testing
|
||||
module Performance
|
||||
DEFAULTS =
|
||||
if benchmark = ARGV.include?('--benchmark') # HAX for rake test
|
||||
{ :benchmark => true,
|
||||
:runs => 4,
|
||||
:metrics => [:wall_time, :memory, :objects, :gc_runs, :gc_time],
|
||||
:output => 'tmp/performance' }
|
||||
else
|
||||
{ :benchmark => false,
|
||||
:runs => 1,
|
||||
:min_percent => 0.01,
|
||||
:metrics => [:process_time, :memory, :objects],
|
||||
:formats => [:flat, :graph_html, :call_tree],
|
||||
:output => 'tmp/performance' }
|
||||
end.freeze
|
||||
|
||||
def self.included(base)
|
||||
base.superclass_delegating_accessor :profile_options
|
||||
base.profile_options = DEFAULTS
|
||||
end
|
||||
|
||||
def full_test_name
|
||||
"#{self.class.name}##{method_name}"
|
||||
end
|
||||
|
||||
def run(result)
|
||||
return if method_name =~ /^default_test$/
|
||||
|
||||
yield(self.class::STARTED, name)
|
||||
@_result = result
|
||||
|
||||
run_warmup
|
||||
if profile_options && metrics = profile_options[:metrics]
|
||||
metrics.each do |metric_name|
|
||||
if klass = Metrics[metric_name.to_sym]
|
||||
run_profile(klass.new)
|
||||
result.add_run
|
||||
end
|
||||
end
|
||||
def self.included(base)
|
||||
base.superclass_delegating_accessor :profile_options
|
||||
base.profile_options = DEFAULTS
|
||||
end
|
||||
|
||||
yield(self.class::FINISHED, name)
|
||||
end
|
||||
def full_test_name
|
||||
"#{self.class.name}##{method_name}"
|
||||
end
|
||||
|
||||
def run_test(metric, mode)
|
||||
run_callbacks :setup
|
||||
setup
|
||||
metric.send(mode) { __send__ @method_name }
|
||||
rescue ::Test::Unit::AssertionFailedError => e
|
||||
add_failure(e.message, e.backtrace)
|
||||
rescue StandardError, ScriptError
|
||||
add_error($!)
|
||||
ensure
|
||||
begin
|
||||
teardown
|
||||
run_callbacks :teardown, :enumerator => :reverse_each
|
||||
def run(result)
|
||||
return if method_name =~ /^default_test$/
|
||||
|
||||
yield(self.class::STARTED, name)
|
||||
@_result = result
|
||||
|
||||
run_warmup
|
||||
if profile_options && metrics = profile_options[:metrics]
|
||||
metrics.each do |metric_name|
|
||||
if klass = Metrics[metric_name.to_sym]
|
||||
run_profile(klass.new)
|
||||
result.add_run
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
yield(self.class::FINISHED, name)
|
||||
end
|
||||
|
||||
def run_test(metric, mode)
|
||||
run_callbacks :setup
|
||||
setup
|
||||
metric.send(mode) { __send__ @method_name }
|
||||
rescue ::Test::Unit::AssertionFailedError => e
|
||||
add_failure(e.message, e.backtrace)
|
||||
rescue StandardError, ScriptError
|
||||
add_error($!)
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
def run_warmup
|
||||
GC.start
|
||||
|
||||
time = Metrics::Time.new
|
||||
run_test(time, :benchmark)
|
||||
puts "%s (%s warmup)" % [full_test_name, time.format(time.total)]
|
||||
|
||||
GC.start
|
||||
end
|
||||
|
||||
def run_profile(metric)
|
||||
klass = profile_options[:benchmark] ? Benchmarker : Profiler
|
||||
performer = klass.new(self, metric)
|
||||
|
||||
performer.run
|
||||
puts performer.report
|
||||
performer.record
|
||||
end
|
||||
|
||||
class Performer
|
||||
delegate :run_test, :profile_options, :full_test_name, :to => :@harness
|
||||
|
||||
def initialize(harness, metric)
|
||||
@harness, @metric = harness, metric
|
||||
end
|
||||
|
||||
def report
|
||||
rate = @total / profile_options[:runs]
|
||||
'%20s: %s' % [@metric.name, @metric.format(rate)]
|
||||
end
|
||||
|
||||
protected
|
||||
def output_filename
|
||||
"#{profile_options[:output]}/#{full_test_name}_#{@metric.name}"
|
||||
end
|
||||
end
|
||||
|
||||
class Benchmarker < Performer
|
||||
def run
|
||||
profile_options[:runs].to_i.times { run_test(@metric, :benchmark) }
|
||||
@total = @metric.total
|
||||
end
|
||||
|
||||
def record
|
||||
avg = @metric.total / profile_options[:runs].to_i
|
||||
now = Time.now.utc.xmlschema
|
||||
with_output_file do |file|
|
||||
file.puts "#{avg},#{now},#{environment}"
|
||||
end
|
||||
end
|
||||
|
||||
def environment
|
||||
unless defined? @env
|
||||
app = "#{$1}.#{$2}" if File.directory?('.git') && `git branch -v` =~ /^\* (\S+)\s+(\S+)/
|
||||
|
||||
rails = Rails::VERSION::STRING
|
||||
if File.directory?('vendor/rails/.git')
|
||||
Dir.chdir('vendor/rails') do
|
||||
rails += ".#{$1}.#{$2}" if `git branch -v` =~ /^\* (\S+)\s+(\S+)/
|
||||
end
|
||||
end
|
||||
|
||||
ruby = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
|
||||
ruby += "-#{RUBY_VERSION}.#{RUBY_PATCHLEVEL}"
|
||||
|
||||
@env = [app, rails, ruby, RUBY_PLATFORM] * ','
|
||||
end
|
||||
|
||||
@env
|
||||
end
|
||||
|
||||
protected
|
||||
HEADER = 'measurement,created_at,app,rails,ruby,platform'
|
||||
|
||||
def with_output_file
|
||||
fname = output_filename
|
||||
|
||||
if new = !File.exist?(fname)
|
||||
FileUtils.mkdir_p(File.dirname(fname))
|
||||
end
|
||||
|
||||
File.open(fname, 'ab') do |file|
|
||||
file.puts(HEADER) if new
|
||||
yield file
|
||||
end
|
||||
end
|
||||
|
||||
def output_filename
|
||||
"#{super}.csv"
|
||||
end
|
||||
end
|
||||
|
||||
class Profiler < Performer
|
||||
def initialize(*args)
|
||||
super
|
||||
@supported = @metric.measure_mode rescue false
|
||||
end
|
||||
|
||||
def run
|
||||
return unless @supported
|
||||
|
||||
RubyProf.measure_mode = @metric.measure_mode
|
||||
RubyProf.start
|
||||
RubyProf.pause
|
||||
profile_options[:runs].to_i.times { run_test(@metric, :profile) }
|
||||
@data = RubyProf.stop
|
||||
@total = @data.threads.values.sum(0) { |method_infos| method_infos.sort.last.total_time }
|
||||
end
|
||||
|
||||
def report
|
||||
if @supported
|
||||
super
|
||||
else
|
||||
'%20s: unsupported' % @metric.name
|
||||
end
|
||||
end
|
||||
|
||||
def record
|
||||
return unless @supported
|
||||
|
||||
klasses = profile_options[:formats].map { |f| RubyProf.const_get("#{f.to_s.camelize}Printer") }.compact
|
||||
|
||||
klasses.each do |klass|
|
||||
fname = output_filename(klass)
|
||||
FileUtils.mkdir_p(File.dirname(fname))
|
||||
File.open(fname, 'wb') do |file|
|
||||
klass.new(@data).print(file, profile_options.slice(:min_percent))
|
||||
end
|
||||
ensure
|
||||
begin
|
||||
teardown
|
||||
run_callbacks :teardown, :enumerator => :reverse_each
|
||||
rescue ::Test::Unit::AssertionFailedError => e
|
||||
add_failure(e.message, e.backtrace)
|
||||
rescue StandardError, ScriptError
|
||||
add_error($!)
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
def output_filename(printer_class)
|
||||
suffix =
|
||||
case printer_class.name.demodulize
|
||||
when 'FlatPrinter'; 'flat.txt'
|
||||
when 'GraphPrinter'; 'graph.txt'
|
||||
when 'GraphHtmlPrinter'; 'graph.html'
|
||||
when 'CallTreePrinter'; 'tree.txt'
|
||||
else printer_class.name.sub(/Printer$/, '').underscore
|
||||
end
|
||||
def run_warmup
|
||||
GC.start
|
||||
|
||||
"#{super()}_#{suffix}"
|
||||
end
|
||||
end
|
||||
time = Metrics::Time.new
|
||||
run_test(time, :benchmark)
|
||||
puts "%s (%s warmup)" % [full_test_name, time.format(time.total)]
|
||||
|
||||
module Metrics
|
||||
def self.[](name)
|
||||
const_get(name.to_s.camelize)
|
||||
rescue NameError
|
||||
nil
|
||||
end
|
||||
|
||||
class Base
|
||||
attr_reader :total
|
||||
|
||||
def initialize
|
||||
@total = 0
|
||||
GC.start
|
||||
end
|
||||
|
||||
def name
|
||||
@name ||= self.class.name.demodulize.underscore
|
||||
def run_profile(metric)
|
||||
klass = profile_options[:benchmark] ? Benchmarker : Profiler
|
||||
performer = klass.new(self, metric)
|
||||
|
||||
performer.run
|
||||
puts performer.report
|
||||
performer.record
|
||||
end
|
||||
|
||||
def measure_mode
|
||||
self.class::Mode
|
||||
class Performer
|
||||
delegate :run_test, :profile_options, :full_test_name, :to => :@harness
|
||||
|
||||
def initialize(harness, metric)
|
||||
@harness, @metric = harness, metric
|
||||
end
|
||||
|
||||
def measure
|
||||
0
|
||||
end
|
||||
|
||||
def benchmark
|
||||
with_gc_stats do
|
||||
before = measure
|
||||
yield
|
||||
@total += (measure - before)
|
||||
end
|
||||
end
|
||||
|
||||
def profile
|
||||
RubyProf.resume
|
||||
yield
|
||||
ensure
|
||||
RubyProf.pause
|
||||
def report
|
||||
rate = @total / profile_options[:runs]
|
||||
'%20s: %s' % [@metric.name, @metric.format(rate)]
|
||||
end
|
||||
|
||||
protected
|
||||
if GC.respond_to?(:enable_stats)
|
||||
def with_gc_stats
|
||||
GC.enable_stats
|
||||
yield
|
||||
ensure
|
||||
GC.disable_stats
|
||||
end
|
||||
elsif defined?(GC::Profiler)
|
||||
def with_gc_stats
|
||||
GC.start
|
||||
GC.disable
|
||||
GC::Profiler.enable
|
||||
yield
|
||||
ensure
|
||||
GC::Profiler.disable
|
||||
GC.enable
|
||||
end
|
||||
else
|
||||
def with_gc_stats
|
||||
yield
|
||||
end
|
||||
def output_filename
|
||||
"#{profile_options[:output]}/#{full_test_name}_#{@metric.name}"
|
||||
end
|
||||
end
|
||||
|
||||
class Time < Base
|
||||
def measure
|
||||
::Time.now.to_f
|
||||
class Benchmarker < Performer
|
||||
def run
|
||||
profile_options[:runs].to_i.times { run_test(@metric, :benchmark) }
|
||||
@total = @metric.total
|
||||
end
|
||||
|
||||
def format(measurement)
|
||||
if measurement < 2
|
||||
'%d ms' % (measurement * 1000)
|
||||
else
|
||||
'%.2f sec' % measurement
|
||||
def record
|
||||
avg = @metric.total / profile_options[:runs].to_i
|
||||
now = Time.now.utc.xmlschema
|
||||
with_output_file do |file|
|
||||
file.puts "#{avg},#{now},#{environment}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class ProcessTime < Time
|
||||
Mode = RubyProf::PROCESS_TIME
|
||||
def environment
|
||||
unless defined? @env
|
||||
app = "#{$1}.#{$2}" if File.directory?('.git') && `git branch -v` =~ /^\* (\S+)\s+(\S+)/
|
||||
|
||||
def measure
|
||||
RubyProf.measure_process_time
|
||||
rails = Rails::VERSION::STRING
|
||||
if File.directory?('vendor/rails/.git')
|
||||
Dir.chdir('vendor/rails') do
|
||||
rails += ".#{$1}.#{$2}" if `git branch -v` =~ /^\* (\S+)\s+(\S+)/
|
||||
end
|
||||
end
|
||||
|
||||
ruby = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
|
||||
ruby += "-#{RUBY_VERSION}.#{RUBY_PATCHLEVEL}"
|
||||
|
||||
@env = [app, rails, ruby, RUBY_PLATFORM] * ','
|
||||
end
|
||||
|
||||
@env
|
||||
end
|
||||
|
||||
protected
|
||||
HEADER = 'measurement,created_at,app,rails,ruby,platform'
|
||||
|
||||
def with_output_file
|
||||
fname = output_filename
|
||||
|
||||
if new = !File.exist?(fname)
|
||||
FileUtils.mkdir_p(File.dirname(fname))
|
||||
end
|
||||
|
||||
File.open(fname, 'ab') do |file|
|
||||
file.puts(HEADER) if new
|
||||
yield file
|
||||
end
|
||||
end
|
||||
|
||||
def output_filename
|
||||
"#{super}.csv"
|
||||
end
|
||||
end
|
||||
|
||||
class WallTime < Time
|
||||
Mode = RubyProf::WALL_TIME
|
||||
|
||||
def measure
|
||||
RubyProf.measure_wall_time
|
||||
end
|
||||
end
|
||||
|
||||
class CpuTime < Time
|
||||
Mode = RubyProf::CPU_TIME if RubyProf.const_defined?(:CPU_TIME)
|
||||
|
||||
class Profiler < Performer
|
||||
def initialize(*args)
|
||||
# FIXME: yeah my CPU is 2.33 GHz
|
||||
RubyProf.cpu_frequency = 2.33e9
|
||||
super
|
||||
@supported = @metric.measure_mode rescue false
|
||||
end
|
||||
|
||||
def measure
|
||||
RubyProf.measure_cpu_time
|
||||
def run
|
||||
return unless @supported
|
||||
|
||||
RubyProf.measure_mode = @metric.measure_mode
|
||||
RubyProf.start
|
||||
RubyProf.pause
|
||||
profile_options[:runs].to_i.times { run_test(@metric, :profile) }
|
||||
@data = RubyProf.stop
|
||||
@total = @data.threads.values.sum(0) { |method_infos| method_infos.sort.last.total_time }
|
||||
end
|
||||
|
||||
def report
|
||||
if @supported
|
||||
super
|
||||
else
|
||||
'%20s: unsupported' % @metric.name
|
||||
end
|
||||
end
|
||||
|
||||
def record
|
||||
return unless @supported
|
||||
|
||||
klasses = profile_options[:formats].map { |f| RubyProf.const_get("#{f.to_s.camelize}Printer") }.compact
|
||||
|
||||
klasses.each do |klass|
|
||||
fname = output_filename(klass)
|
||||
FileUtils.mkdir_p(File.dirname(fname))
|
||||
File.open(fname, 'wb') do |file|
|
||||
klass.new(@data).print(file, profile_options.slice(:min_percent))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
def output_filename(printer_class)
|
||||
suffix =
|
||||
case printer_class.name.demodulize
|
||||
when 'FlatPrinter'; 'flat.txt'
|
||||
when 'GraphPrinter'; 'graph.txt'
|
||||
when 'GraphHtmlPrinter'; 'graph.html'
|
||||
when 'CallTreePrinter'; 'tree.txt'
|
||||
else printer_class.name.sub(/Printer$/, '').underscore
|
||||
end
|
||||
|
||||
"#{super()}_#{suffix}"
|
||||
end
|
||||
end
|
||||
|
||||
class Memory < Base
|
||||
Mode = RubyProf::MEMORY if RubyProf.const_defined?(:MEMORY)
|
||||
module Metrics
|
||||
def self.[](name)
|
||||
const_get(name.to_s.camelize)
|
||||
rescue NameError
|
||||
nil
|
||||
end
|
||||
|
||||
# ruby-prof wrapper
|
||||
if RubyProf.respond_to?(:measure_memory)
|
||||
def measure
|
||||
RubyProf.measure_memory / 1024.0
|
||||
class Base
|
||||
attr_reader :total
|
||||
|
||||
def initialize
|
||||
@total = 0
|
||||
end
|
||||
|
||||
# Ruby 1.8 + railsbench patch
|
||||
elsif GC.respond_to?(:allocated_size)
|
||||
def measure
|
||||
GC.allocated_size / 1024.0
|
||||
def name
|
||||
@name ||= self.class.name.demodulize.underscore
|
||||
end
|
||||
|
||||
# Ruby 1.8 + lloyd patch
|
||||
elsif GC.respond_to?(:heap_info)
|
||||
def measure
|
||||
GC.heap_info['heap_current_memory'] / 1024.0
|
||||
def measure_mode
|
||||
self.class::Mode
|
||||
end
|
||||
|
||||
# Ruby 1.9 with total_malloc_allocated_size patch
|
||||
elsif GC.respond_to?(:malloc_total_allocated_size)
|
||||
def measure
|
||||
GC.total_malloc_allocated_size / 1024.0
|
||||
0
|
||||
end
|
||||
|
||||
# Ruby 1.9 unpatched
|
||||
elsif GC.respond_to?(:malloc_allocated_size)
|
||||
def measure
|
||||
GC.malloc_allocated_size / 1024.0
|
||||
def benchmark
|
||||
with_gc_stats do
|
||||
before = measure
|
||||
yield
|
||||
@total += (measure - before)
|
||||
end
|
||||
end
|
||||
|
||||
# Ruby 1.9 + GC profiler patch
|
||||
elsif defined?(GC::Profiler)
|
||||
def profile
|
||||
RubyProf.resume
|
||||
yield
|
||||
ensure
|
||||
RubyProf.pause
|
||||
end
|
||||
|
||||
protected
|
||||
if GC.respond_to?(:enable_stats)
|
||||
def with_gc_stats
|
||||
GC.enable_stats
|
||||
yield
|
||||
ensure
|
||||
GC.disable_stats
|
||||
end
|
||||
elsif defined?(GC::Profiler)
|
||||
def with_gc_stats
|
||||
GC.start
|
||||
GC.disable
|
||||
GC::Profiler.enable
|
||||
yield
|
||||
ensure
|
||||
GC::Profiler.disable
|
||||
GC.enable
|
||||
end
|
||||
else
|
||||
def with_gc_stats
|
||||
yield
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Time < Base
|
||||
def measure
|
||||
GC.enable
|
||||
GC.start
|
||||
kb = GC::Profiler.data.last[:HEAP_USE_SIZE] / 1024.0
|
||||
GC.disable
|
||||
kb
|
||||
::Time.now.to_f
|
||||
end
|
||||
|
||||
def format(measurement)
|
||||
if measurement < 2
|
||||
'%d ms' % (measurement * 1000)
|
||||
else
|
||||
'%.2f sec' % measurement
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def format(measurement)
|
||||
'%.2f KB' % measurement
|
||||
end
|
||||
end
|
||||
class ProcessTime < Time
|
||||
Mode = RubyProf::PROCESS_TIME
|
||||
|
||||
class Objects < Base
|
||||
Mode = RubyProf::ALLOCATIONS if RubyProf.const_defined?(:ALLOCATIONS)
|
||||
|
||||
if RubyProf.respond_to?(:measure_allocations)
|
||||
def measure
|
||||
RubyProf.measure_allocations
|
||||
end
|
||||
|
||||
# Ruby 1.8 + railsbench patch
|
||||
elsif ObjectSpace.respond_to?(:allocated_objects)
|
||||
def measure
|
||||
ObjectSpace.allocated_objects
|
||||
end
|
||||
|
||||
# Ruby 1.9 + GC profiler patch
|
||||
elsif defined?(GC::Profiler)
|
||||
def measure
|
||||
GC.enable
|
||||
GC.start
|
||||
last = GC::Profiler.data.last
|
||||
count = last[:HEAP_LIVE_OBJECTS] + last[:HEAP_FREE_OBJECTS]
|
||||
GC.disable
|
||||
count
|
||||
RubyProf.measure_process_time
|
||||
end
|
||||
end
|
||||
|
||||
def format(measurement)
|
||||
measurement.to_i.to_s
|
||||
end
|
||||
end
|
||||
class WallTime < Time
|
||||
Mode = RubyProf::WALL_TIME
|
||||
|
||||
class GcRuns < Base
|
||||
Mode = RubyProf::GC_RUNS if RubyProf.const_defined?(:GC_RUNS)
|
||||
|
||||
if RubyProf.respond_to?(:measure_gc_runs)
|
||||
def measure
|
||||
RubyProf.measure_gc_runs
|
||||
end
|
||||
elsif GC.respond_to?(:collections)
|
||||
def measure
|
||||
GC.collections
|
||||
end
|
||||
elsif GC.respond_to?(:heap_info)
|
||||
def measure
|
||||
GC.heap_info['num_gc_passes']
|
||||
RubyProf.measure_wall_time
|
||||
end
|
||||
end
|
||||
|
||||
def format(measurement)
|
||||
measurement.to_i.to_s
|
||||
end
|
||||
end
|
||||
class CpuTime < Time
|
||||
Mode = RubyProf::CPU_TIME if RubyProf.const_defined?(:CPU_TIME)
|
||||
|
||||
class GcTime < Base
|
||||
Mode = RubyProf::GC_TIME if RubyProf.const_defined?(:GC_TIME)
|
||||
|
||||
if RubyProf.respond_to?(:measure_gc_time)
|
||||
def measure
|
||||
RubyProf.measure_gc_time
|
||||
def initialize(*args)
|
||||
# FIXME: yeah my CPU is 2.33 GHz
|
||||
RubyProf.cpu_frequency = 2.33e9
|
||||
super
|
||||
end
|
||||
elsif GC.respond_to?(:time)
|
||||
|
||||
def measure
|
||||
GC.time
|
||||
RubyProf.measure_cpu_time
|
||||
end
|
||||
end
|
||||
|
||||
def format(measurement)
|
||||
'%d ms' % (measurement / 1000)
|
||||
class Memory < Base
|
||||
Mode = RubyProf::MEMORY if RubyProf.const_defined?(:MEMORY)
|
||||
|
||||
# ruby-prof wrapper
|
||||
if RubyProf.respond_to?(:measure_memory)
|
||||
def measure
|
||||
RubyProf.measure_memory / 1024.0
|
||||
end
|
||||
|
||||
# Ruby 1.8 + railsbench patch
|
||||
elsif GC.respond_to?(:allocated_size)
|
||||
def measure
|
||||
GC.allocated_size / 1024.0
|
||||
end
|
||||
|
||||
# Ruby 1.8 + lloyd patch
|
||||
elsif GC.respond_to?(:heap_info)
|
||||
def measure
|
||||
GC.heap_info['heap_current_memory'] / 1024.0
|
||||
end
|
||||
|
||||
# Ruby 1.9 with total_malloc_allocated_size patch
|
||||
elsif GC.respond_to?(:malloc_total_allocated_size)
|
||||
def measure
|
||||
GC.total_malloc_allocated_size / 1024.0
|
||||
end
|
||||
|
||||
# Ruby 1.9 unpatched
|
||||
elsif GC.respond_to?(:malloc_allocated_size)
|
||||
def measure
|
||||
GC.malloc_allocated_size / 1024.0
|
||||
end
|
||||
|
||||
# Ruby 1.9 + GC profiler patch
|
||||
elsif defined?(GC::Profiler)
|
||||
def measure
|
||||
GC.enable
|
||||
GC.start
|
||||
kb = GC::Profiler.data.last[:HEAP_USE_SIZE] / 1024.0
|
||||
GC.disable
|
||||
kb
|
||||
end
|
||||
end
|
||||
|
||||
def format(measurement)
|
||||
'%.2f KB' % measurement
|
||||
end
|
||||
end
|
||||
|
||||
class Objects < Base
|
||||
Mode = RubyProf::ALLOCATIONS if RubyProf.const_defined?(:ALLOCATIONS)
|
||||
|
||||
if RubyProf.respond_to?(:measure_allocations)
|
||||
def measure
|
||||
RubyProf.measure_allocations
|
||||
end
|
||||
|
||||
# Ruby 1.8 + railsbench patch
|
||||
elsif ObjectSpace.respond_to?(:allocated_objects)
|
||||
def measure
|
||||
ObjectSpace.allocated_objects
|
||||
end
|
||||
|
||||
# Ruby 1.9 + GC profiler patch
|
||||
elsif defined?(GC::Profiler)
|
||||
def measure
|
||||
GC.enable
|
||||
GC.start
|
||||
last = GC::Profiler.data.last
|
||||
count = last[:HEAP_LIVE_OBJECTS] + last[:HEAP_FREE_OBJECTS]
|
||||
GC.disable
|
||||
count
|
||||
end
|
||||
end
|
||||
|
||||
def format(measurement)
|
||||
measurement.to_i.to_s
|
||||
end
|
||||
end
|
||||
|
||||
class GcRuns < Base
|
||||
Mode = RubyProf::GC_RUNS if RubyProf.const_defined?(:GC_RUNS)
|
||||
|
||||
if RubyProf.respond_to?(:measure_gc_runs)
|
||||
def measure
|
||||
RubyProf.measure_gc_runs
|
||||
end
|
||||
elsif GC.respond_to?(:collections)
|
||||
def measure
|
||||
GC.collections
|
||||
end
|
||||
elsif GC.respond_to?(:heap_info)
|
||||
def measure
|
||||
GC.heap_info['num_gc_passes']
|
||||
end
|
||||
end
|
||||
|
||||
def format(measurement)
|
||||
measurement.to_i.to_s
|
||||
end
|
||||
end
|
||||
|
||||
class GcTime < Base
|
||||
Mode = RubyProf::GC_TIME if RubyProf.const_defined?(:GC_TIME)
|
||||
|
||||
if RubyProf.respond_to?(:measure_gc_time)
|
||||
def measure
|
||||
RubyProf.measure_gc_time
|
||||
end
|
||||
elsif GC.respond_to?(:time)
|
||||
def measure
|
||||
GC.time
|
||||
end
|
||||
end
|
||||
|
||||
def format(measurement)
|
||||
'%d ms' % (measurement / 1000)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
rescue LoadError
|
||||
end
|
80
activesupport/test/autoload.rb
Normal file
80
activesupport/test/autoload.rb
Normal file
|
@ -0,0 +1,80 @@
|
|||
require 'abstract_unit'
|
||||
|
||||
class TestAutoloadModule < ActiveSupport::TestCase
|
||||
include ActiveSupport::Testing::Isolation
|
||||
|
||||
module ::Fixtures
|
||||
extend ActiveSupport::Autoload
|
||||
|
||||
module Autoload
|
||||
extend ActiveSupport::Autoload
|
||||
end
|
||||
end
|
||||
|
||||
test "the autoload module works like normal autoload" do
|
||||
module ::Fixtures::Autoload
|
||||
autoload :SomeClass, "fixtures/autoload/some_class"
|
||||
end
|
||||
|
||||
assert_nothing_raised { ::Fixtures::Autoload::SomeClass }
|
||||
end
|
||||
|
||||
test "when specifying an :eager constant it still works like normal autoload by default" do
|
||||
module ::Fixtures::Autoload
|
||||
autoload :SomeClass, "fixtures/autoload/some_class"
|
||||
end
|
||||
|
||||
assert !$LOADED_FEATURES.include?("fixtures/autoload/some_class.rb")
|
||||
assert_nothing_raised { ::Fixtures::Autoload::SomeClass }
|
||||
end
|
||||
|
||||
test ":eager constants can be triggered via ActiveSupport::Autoload.eager_autoload!" do
|
||||
module ::Fixtures::Autoload
|
||||
autoload :SomeClass, "fixtures/autoload/some_class"
|
||||
end
|
||||
ActiveSupport::Autoload.eager_autoload!
|
||||
assert $LOADED_FEATURES.include?("fixtures/autoload/some_class.rb")
|
||||
assert_nothing_raised { ::Fixtures::Autoload::SomeClass }
|
||||
end
|
||||
|
||||
test "the location of autoloaded constants defaults to :name.underscore" do
|
||||
module ::Fixtures::Autoload
|
||||
autoload :SomeClass
|
||||
end
|
||||
|
||||
assert !$LOADED_FEATURES.include?("fixtures/autoload/some_class.rb")
|
||||
assert_nothing_raised { ::Fixtures::Autoload::SomeClass }
|
||||
end
|
||||
|
||||
test "the location of :eager autoloaded constants defaults to :name.underscore" do
|
||||
module ::Fixtures::Autoload
|
||||
autoload :SomeClass
|
||||
end
|
||||
|
||||
ActiveSupport::Autoload.eager_autoload!
|
||||
assert $LOADED_FEATURES.include?("fixtures/autoload/some_class.rb")
|
||||
assert_nothing_raised { ::Fixtures::Autoload::SomeClass }
|
||||
end
|
||||
|
||||
test "a directory for a block of autoloads can be specified" do
|
||||
module ::Fixtures
|
||||
autoload_under "autoload" do
|
||||
autoload :AnotherClass
|
||||
end
|
||||
end
|
||||
|
||||
assert !$LOADED_FEATURES.include?("fixtures/autoload/another_class.rb")
|
||||
assert_nothing_raised { ::Fixtures::AnotherClass }
|
||||
end
|
||||
|
||||
test "a path for a block of autoloads can be specified" do
|
||||
module ::Fixtures
|
||||
autoload_at "fixtures/autoload/another_class" do
|
||||
autoload :AnotherClass
|
||||
end
|
||||
end
|
||||
|
||||
assert !$LOADED_FEATURES.include?("fixtures/autoload/another_class.rb")
|
||||
assert_nothing_raised { ::Fixtures::AnotherClass }
|
||||
end
|
||||
end
|
2
activesupport/test/fixtures/autoload/another_class.rb
vendored
Normal file
2
activesupport/test/fixtures/autoload/another_class.rb
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
class Fixtures::AnotherClass
|
||||
end
|
2
activesupport/test/fixtures/autoload/some_class.rb
vendored
Normal file
2
activesupport/test/fixtures/autoload/some_class.rb
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
class Fixtures::Autoload::SomeClass
|
||||
end
|
|
@ -1,6 +1,7 @@
|
|||
require 'active_support/all'
|
||||
require 'active_support/test_case'
|
||||
require 'action_controller'
|
||||
require 'action_dispatch/test_case'
|
||||
|
||||
# work around the at_exit hook in test/unit, which kills IRB
|
||||
Test::Unit.run = true if Test::Unit.respond_to?(:run=)
|
||||
|
|
|
@ -8,8 +8,14 @@ gem "rack-test", "~> 0.5.0"
|
|||
|
||||
require 'test/unit'
|
||||
require 'active_support/core_ext/kernel/requires'
|
||||
|
||||
# AP is always present
|
||||
require 'action_controller/test_case'
|
||||
require 'action_view/test_case'
|
||||
require 'action_dispatch/test_case'
|
||||
|
||||
require 'action_mailer/test_case' if defined?(ActionMailer)
|
||||
require 'active_model/test_case' if defined?(ActiveModel)
|
||||
|
||||
if defined?(ActiveRecord)
|
||||
require 'active_record/test_case'
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require 'abstract_unit'
|
||||
require 'action_controller'
|
||||
require 'action_controller/test_case'
|
||||
|
||||
require 'rails/info'
|
||||
require 'rails/info_controller'
|
||||
|
|
Loading…
Reference in a new issue