diff options
author | David Heinemeier Hansson <david@loudthinking.com> | 2009-12-31 01:15:30 -0500 |
---|---|---|
committer | David Heinemeier Hansson <david@loudthinking.com> | 2009-12-31 01:15:30 -0500 |
commit | 96c27e4003b803b9ac1a3581dfe1c181ba79556a (patch) | |
tree | 24a6c8573dfe3aa01abd4464eafbeb86e96cd250 | |
parent | 5d8342cc325bc9f46bfe61bf3534248b6ad3216f (diff) | |
parent | c4c2502df8b0b7b5fa28d796bdb1d4bd02af4b3d (diff) | |
download | rails-96c27e4003b803b9ac1a3581dfe1c181ba79556a.tar.gz rails-96c27e4003b803b9ac1a3581dfe1c181ba79556a.tar.bz2 rails-96c27e4003b803b9ac1a3581dfe1c181ba79556a.zip |
Merge branch 'master' of github.com:rails/rails
24 files changed, 341 insertions, 559 deletions
diff --git a/actionpack/lib/action_controller/rails.rb b/actionpack/lib/action_controller/rails.rb index 6ebb50887b..df708c315b 100644 --- a/actionpack/lib/action_controller/rails.rb +++ b/actionpack/lib/action_controller/rails.rb @@ -1,7 +1,6 @@ module ActionController class Plugin < Rails::Plugin plugin_name :action_controller - include_modules_in "ActionController::Base" initializer "action_controller.set_configs" do |app| app.config.action_controller.each do |k,v| @@ -91,4 +90,4 @@ module ActionController end end -end
\ No newline at end of file +end diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb index 7f61ff5657..1e87a016f9 100644 --- a/actionpack/lib/action_dispatch.rb +++ b/actionpack/lib/action_dispatch.rb @@ -23,7 +23,7 @@ activesupport_path = File.expand_path('../../../activesupport/lib', __FILE__) $:.unshift(activesupport_path) if File.directory?(activesupport_path) && !$:.include?(activesupport_path) -require 'active_support/ruby/shim' +require 'active_support' require 'active_support/dependencies/autoload' require 'rack' diff --git a/actionpack/test/activerecord/controller_runtime_test.rb b/actionpack/test/activerecord/controller_runtime_test.rb new file mode 100644 index 0000000000..0f534da14b --- /dev/null +++ b/actionpack/test/activerecord/controller_runtime_test.rb @@ -0,0 +1,39 @@ +require 'active_record_unit' +require 'active_record/railties/controller_runtime' +require 'fixtures/project' + +ActionController::Base.send :include, ActiveRecord::Railties::ControllerRuntime + +class ARLoggingController < ActionController::Base + def show + render :inline => "<%= Project.all %>" + end +end + +class ARLoggingTest < ActionController::TestCase + tests ARLoggingController + + def setup + super + set_logger + end + + def wait + ActiveSupport::Notifications.notifier.wait + end + + def test_log_with_active_record + get :show + wait + assert_match /ActiveRecord runtime/, logs[3] + end + + private + def set_logger + @controller.logger = MockLogger.new + end + + def logs + @logs ||= @controller.logger.logged.compact.map {|l| l.to_s.strip} + end +end diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb index 87de480263..a524dc50a1 100644 --- a/activerecord/lib/active_record.rb +++ b/activerecord/lib/active_record.rb @@ -60,7 +60,6 @@ module ActiveRecord autoload :Batches autoload :Calculations autoload :Callbacks - autoload :ControllerRuntime autoload :DynamicFinderMatch autoload :DynamicScopeMatch autoload :Migration diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index b2b3a9789c..1ceb0dbf96 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -485,7 +485,14 @@ module ActiveRecord def callback(method, record) callbacks_for(method).each do |callback| - ActiveSupport::DeprecatedCallbacks::Callback.new(method, callback, record).call(@owner, record) + case callback + when Symbol + @owner.send(callback, record) + when Proc + callback.call(@owner, record) + else + callback.send(method, @owner, record) + end end end diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 07c5545171..c4bdbdad08 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1,4 +1,3 @@ -require 'benchmark' require 'yaml' require 'set' require 'active_support/benchmarkable' diff --git a/activerecord/lib/active_record/callbacks.rb b/activerecord/lib/active_record/callbacks.rb index e1d772bd95..e2a8f03c8f 100644 --- a/activerecord/lib/active_record/callbacks.rb +++ b/activerecord/lib/active_record/callbacks.rb @@ -274,7 +274,7 @@ module ActiveRecord def deprecated_callback_method(symbol) #:nodoc: if respond_to?(symbol) - ActiveSupport::Deprecation.warn("Base##{symbol} has been deprecated, please use Base.#{symbol} :method instead") + ActiveSupport::Deprecation.warn("Overwriting #{symbol} in your models has been deprecated, please use Base##{symbol} :method_name instead") send(symbol) end end diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index 8fae26b790..d09aa3c4d2 100755 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -1,6 +1,7 @@ require 'date' require 'bigdecimal' require 'bigdecimal/util' +require 'active_support/core_ext/benchmark' # TODO: Autoload these files require 'active_record/connection_adapters/abstract/schema_definitions' @@ -191,7 +192,6 @@ module ActiveRecord end def log_info(sql, name, ms) - @runtime += ms if @logger && @logger.debug? name = '%s (%.1fms)' % [name || 'SQL', ms] @logger.debug(format_log_entry(name, sql.squeeze(' '))) @@ -199,8 +199,12 @@ module ActiveRecord end protected - def log(sql, name, &block) - ActiveSupport::Notifications.instrument(:sql, :sql => sql, :name => name, &block) + def log(sql, name) + result = nil + ActiveSupport::Notifications.instrument(:sql, :sql => sql, :name => name) do + @runtime += Benchmark.ms { result = yield } + end + result rescue Exception => e # Log message and raise exception. # Set last_verification to 0, so that connection gets verified diff --git a/activerecord/lib/active_record/controller_runtime.rb b/activerecord/lib/active_record/controller_runtime.rb deleted file mode 100644 index 1281901ae8..0000000000 --- a/activerecord/lib/active_record/controller_runtime.rb +++ /dev/null @@ -1,27 +0,0 @@ -module ActiveRecord - module ControllerRuntime - extend ActiveSupport::Concern - - attr_internal :db_runtime - - def cleanup_view_runtime - if Object.const_defined?("ActiveRecord") && ActiveRecord::Base.connected? - db_rt_before_render = ActiveRecord::Base.connection.reset_runtime - runtime = super - db_rt_after_render = ActiveRecord::Base.connection.reset_runtime - self.db_runtime = db_rt_before_render + db_rt_after_render - runtime - db_rt_after_render - else - super - end - end - - module ClassMethods - def process_log_action(controller) - super - db_runtime = controller.send :db_runtime - logger.info(" ActiveRecord runtime: %.1fms" % db_runtime.to_f) if db_runtime - end - end - end -end
\ No newline at end of file diff --git a/activerecord/lib/active_record/rails.rb b/activerecord/lib/active_record/rails.rb index e7de699974..a13bd2a5da 100644 --- a/activerecord/lib/active_record/rails.rb +++ b/activerecord/lib/active_record/rails.rb @@ -7,12 +7,9 @@ require "action_controller/rails" module ActiveRecord class Plugin < Rails::Plugin plugin_name :active_record - include_modules_in "ActiveRecord::Base" - - config.action_controller.include "ActiveRecord::ControllerRuntime" rake_tasks do - load "active_record/rails/databases.rake" + load "active_record/railties/databases.rake" end initializer "active_record.set_configs" do |app| @@ -33,6 +30,12 @@ module ActiveRecord ActiveRecord::Base.default_timezone = :utc end + # Expose database runtime to controller for logging. + initializer "active_record.log_runtime" do |app| + require "active_record/railties/controller_runtime" + ActionController::Base.send :include, ActiveRecord::Railties::ControllerRuntime + end + # Setup database middleware after initializers have run initializer "active_record.initialize_database_middleware" do |app| middleware = app.config.middleware @@ -51,7 +54,7 @@ module ActiveRecord # TODO: ActiveRecord::Base.logger should delegate to its own config.logger initializer "active_record.logger" do - ActiveRecord::Base.logger ||= Rails.logger + ActiveRecord::Base.logger ||= ::Rails.logger end initializer "active_record.notifications" do @@ -63,4 +66,4 @@ module ActiveRecord end end -end
\ No newline at end of file +end diff --git a/activerecord/lib/active_record/railties/controller_runtime.rb b/activerecord/lib/active_record/railties/controller_runtime.rb new file mode 100644 index 0000000000..535e967ec3 --- /dev/null +++ b/activerecord/lib/active_record/railties/controller_runtime.rb @@ -0,0 +1,31 @@ +require 'active_support/core_ext/module/attr_internal' + +module ActiveRecord + module Railties + module ControllerRuntime + extend ActiveSupport::Concern + + attr_internal :db_runtime + + def cleanup_view_runtime + if ActiveRecord::Base.connected? + db_rt_before_render = ActiveRecord::Base.connection.reset_runtime + runtime = super + db_rt_after_render = ActiveRecord::Base.connection.reset_runtime + self.db_runtime = db_rt_before_render + db_rt_after_render + runtime - db_rt_after_render + else + super + end + end + + module ClassMethods + def log_process_action(controller) + super + db_runtime = controller.send :db_runtime + logger.info(" ActiveRecord runtime: %.1fms" % db_runtime.to_f) if db_runtime + end + end + end + end +end diff --git a/activerecord/lib/active_record/rails/databases.rake b/activerecord/lib/active_record/railties/databases.rake index a35a6c156b..a35a6c156b 100644 --- a/activerecord/lib/active_record/rails/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb index e8a2a72735..12c1f23763 100644 --- a/activerecord/lib/active_record/validations.rb +++ b/activerecord/lib/active_record/validations.rb @@ -17,8 +17,6 @@ module ActiveRecord module Validations extend ActiveSupport::Concern - - include ActiveSupport::DeprecatedCallbacks include ActiveModel::Validations included do diff --git a/activesupport/lib/active_support.rb b/activesupport/lib/active_support.rb index 8215cfaf0d..3463000529 100644 --- a/activesupport/lib/active_support.rb +++ b/activesupport/lib/active_support.rb @@ -50,7 +50,6 @@ module ActiveSupport autoload :Callbacks autoload :Concern autoload :Configurable - autoload :DeprecatedCallbacks autoload :Deprecation autoload :Gzip autoload :Inflector diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 97e2a478b5..05bc453dbf 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -90,7 +90,7 @@ module ActiveSupport class Callback @@_callback_sequence = 0 - attr_accessor :chain, :filter, :kind, :options, :per_key, :klass + attr_accessor :chain, :filter, :kind, :options, :per_key, :klass, :raw_filter def initialize(chain, filter, kind, options, klass) @chain, @kind, @klass = chain, kind, klass diff --git a/activesupport/lib/active_support/deprecated_callbacks.rb b/activesupport/lib/active_support/deprecated_callbacks.rb deleted file mode 100644 index f56fef0b6d..0000000000 --- a/activesupport/lib/active_support/deprecated_callbacks.rb +++ /dev/null @@ -1,284 +0,0 @@ -require 'active_support/core_ext/array/extract_options' -require 'active_support/core_ext/array/wrap' - -module ActiveSupport - # Callbacks are hooks into the lifecycle of an object that allow you to trigger logic - # before or after an alteration of the object state. - # - # Mixing in this module allows you to define callbacks in your class. - # - # Example: - # class Storage - # include ActiveSupport::DeprecatedCallbacks - # - # define_callbacks :before_save, :after_save - # end - # - # class ConfigStorage < Storage - # before_save :saving_message - # def saving_message - # puts "saving..." - # end - # - # after_save do |object| - # puts "saved" - # end - # - # def save - # run_callbacks(:before_save) - # puts "- save" - # run_callbacks(:after_save) - # end - # end - # - # config = ConfigStorage.new - # config.save - # - # Output: - # saving... - # - save - # saved - # - # Callbacks from parent classes are inherited. - # - # Example: - # class Storage - # include ActiveSupport::DeprecatedCallbacks - # - # define_callbacks :before_save, :after_save - # - # before_save :prepare - # def prepare - # puts "preparing save" - # end - # end - # - # class ConfigStorage < Storage - # before_save :saving_message - # def saving_message - # puts "saving..." - # end - # - # after_save do |object| - # puts "saved" - # end - # - # def save - # run_callbacks(:before_save) - # puts "- save" - # run_callbacks(:after_save) - # end - # end - # - # config = ConfigStorage.new - # config.save - # - # Output: - # preparing save - # saving... - # - save - # saved - module DeprecatedCallbacks - class CallbackChain < Array - def self.build(kind, *methods, &block) - methods, options = extract_options(*methods, &block) - methods.map! { |method| Callback.new(kind, method, options) } - new(methods) - end - - def run(object, options = {}, &terminator) - enumerator = options[:enumerator] || :each - - unless block_given? - send(enumerator) { |callback| callback.call(object) } - else - send(enumerator) do |callback| - result = callback.call(object) - break result if terminator.call(result, object) - end - end - end - - # TODO: Decompose into more Array like behavior - def replace_or_append!(chain) - if index = index(chain) - self[index] = chain - else - self << chain - end - self - end - - def find(callback, &block) - select { |c| c == callback && (!block_given? || yield(c)) }.first - end - - def delete(callback) - super(callback.is_a?(Callback) ? callback : find(callback)) - end - - private - def self.extract_options(*methods, &block) - methods.flatten! - options = methods.extract_options! - methods << block if block_given? - return methods, options - end - - def extract_options(*methods, &block) - self.class.extract_options(*methods, &block) - end - end - - class Callback - attr_reader :kind, :method, :identifier, :options - - def initialize(kind, method, options = {}) - @kind = kind - @method = method - @identifier = options[:identifier] - @options = options - end - - def ==(other) - case other - when Callback - (self.identifier && self.identifier == other.identifier) || self.method == other.method - else - (self.identifier && self.identifier == other) || self.method == other - end - end - - def eql?(other) - self == other - end - - def dup - self.class.new(@kind, @method, @options.dup) - end - - def hash - if @identifier - @identifier.hash - else - @method.hash - end - end - - def call(*args, &block) - evaluate_method(method, *args, &block) if should_run_callback?(*args) - rescue LocalJumpError - raise ArgumentError, - "Cannot yield from a Proc type filter. The Proc must take two " + - "arguments and execute #call on the second argument." - end - - private - def evaluate_method(method, *args, &block) - case method - when Symbol - object = args.shift - object.send(method, *args, &block) - when String - eval(method, args.first.instance_eval { binding }) - when Proc, Method - method.call(*args, &block) - else - if method.respond_to?(kind) - method.send(kind, *args, &block) - else - raise ArgumentError, - "Callbacks must be a symbol denoting the method to call, a string to be evaluated, " + - "a block to be invoked, or an object responding to the callback method." - end - end - end - - def should_run_callback?(*args) - Array.wrap(options[:if]).flatten.compact.all? { |a| evaluate_method(a, *args) } && - !Array.wrap(options[:unless]).flatten.compact.any? { |a| evaluate_method(a, *args) } - end - end - - def self.included(base) - base.extend ClassMethods - end - - module ClassMethods - def define_callbacks(*callbacks) - ActiveSupport::Deprecation.warn('ActiveSupport::DeprecatedCallbacks has been deprecated in favor of ActiveSupport::Callbacks', caller) - - callbacks.each do |callback| - class_eval <<-"end_eval", __FILE__, __LINE__ + 1 - def self.#{callback}(*methods, &block) # def self.before_save(*methods, &block) - callbacks = CallbackChain.build(:#{callback}, *methods, &block) # callbacks = CallbackChain.build(:before_save, *methods, &block) - @#{callback}_callbacks ||= CallbackChain.new # @before_save_callbacks ||= CallbackChain.new - @#{callback}_callbacks.concat callbacks # @before_save_callbacks.concat callbacks - end # end - # - def self.#{callback}_callback_chain # def self.before_save_callback_chain - @#{callback}_callbacks ||= CallbackChain.new # @before_save_callbacks ||= CallbackChain.new - # - if superclass.respond_to?(:#{callback}_callback_chain) # if superclass.respond_to?(:before_save_callback_chain) - CallbackChain.new( # CallbackChain.new( - superclass.#{callback}_callback_chain + # superclass.before_save_callback_chain + - @#{callback}_callbacks # @before_save_callbacks - ) # ) - else # else - @#{callback}_callbacks # @before_save_callbacks - end # end - end # end - end_eval - end - end - end - - # Runs all the callbacks defined for the given options. - # - # If a block is given it will be called after each callback receiving as arguments: - # - # * the result from the callback - # * the object which has the callback - # - # If the result from the block evaluates to +true+, the callback chain is stopped. - # - # Example: - # class Storage - # include ActiveSupport::DeprecatedCallbacks - # - # define_callbacks :before_save, :after_save - # end - # - # class ConfigStorage < Storage - # before_save :pass - # before_save :pass - # before_save :stop - # before_save :pass - # - # def pass - # puts "pass" - # end - # - # def stop - # puts "stop" - # return false - # end - # - # def save - # result = run_callbacks(:before_save) { |result, object| result == false } - # puts "- save" if result - # end - # end - # - # config = ConfigStorage.new - # config.save - # - # Output: - # pass - # pass - # stop - def run_callbacks(kind, options = {}, &block) - self.class.send("#{kind}_callback_chain").run(self, options, &block) - end - end -end diff --git a/activesupport/lib/active_support/testing/isolation.rb b/activesupport/lib/active_support/testing/isolation.rb index 81f7e3c9df..453f4fcc0f 100644 --- a/activesupport/lib/active_support/testing/isolation.rb +++ b/activesupport/lib/active_support/testing/isolation.rb @@ -36,28 +36,56 @@ module ActiveSupport !ENV["NO_FORK"] && RUBY_PLATFORM !~ /mswin|mingw|java/ end - def run(result) - unless defined?(@@ran_class_setup) - self.class.setup if self.class.respond_to?(:setup) - @@ran_class_setup = true + def self.included(base) + if defined?(::MiniTest) && base < ::MiniTest::Unit::TestCase + base.send :include, MiniTest + elsif defined?(Test::Unit) + base.send :include, TestUnit end + end + + module TestUnit + def run(result) + unless defined?(@@ran_class_setup) + self.class.setup if self.class.respond_to?(:setup) + @@ran_class_setup = true + end - yield(Test::Unit::TestCase::STARTED, name) + yield(Test::Unit::TestCase::STARTED, name) - @_result = result + @_result = result - serialized = run_in_isolation do |proxy| - begin - super(proxy) { } - rescue Exception => e - proxy.add_error(Test::Unit::Error.new(name, e)) + serialized = run_in_isolation do |proxy| + begin + super(proxy) { } + rescue Exception => e + proxy.add_error(Test::Unit::Error.new(name, e)) + end end + + retval, proxy = Marshal.load(serialized) + proxy.__replay__(@_result) + + yield(Test::Unit::TestCase::FINISHED, name) + retval end + end - proxy = Marshal.load(serialized) - proxy.__replay__(@_result) + module MiniTest + def run(runner) + unless defined?(@@ran_class_setup) + self.class.setup if self.class.respond_to?(:setup) + @@ran_class_setup = true + end - yield(Test::Unit::TestCase::FINISHED, name) + serialized = run_in_isolation do |runner| + super(runner) + end + + retval, proxy = Marshal.load(serialized) + proxy.__replay__(runner) + retval + end end module Forking @@ -67,8 +95,8 @@ module ActiveSupport pid = fork do read.close proxy = ProxyTestResult.new - yield proxy - write.puts [Marshal.dump(proxy)].pack("m") + retval = yield proxy + write.puts [Marshal.dump([retval, proxy])].pack("m") exit! end @@ -87,9 +115,9 @@ module ActiveSupport if ENV["ISOLATION_TEST"] proxy = ProxyTestResult.new - yield proxy + retval = yield proxy File.open(ENV["ISOLATION_OUTPUT"], "w") do |file| - file.puts [Marshal.dump(proxy)].pack("m") + file.puts [Marshal.dump([retval, proxy])].pack("m") end exit! else diff --git a/activesupport/lib/active_support/testing/setup_and_teardown.rb b/activesupport/lib/active_support/testing/setup_and_teardown.rb index 0e998d2dbe..6ce9495cee 100644 --- a/activesupport/lib/active_support/testing/setup_and_teardown.rb +++ b/activesupport/lib/active_support/testing/setup_and_teardown.rb @@ -1,16 +1,26 @@ module ActiveSupport module Testing module SetupAndTeardown - def self.included(base) - base.class_eval do - include ActiveSupport::DeprecatedCallbacks - define_callbacks :setup, :teardown + extend ActiveSupport::Concern - if defined?(MiniTest::Assertions) && TestCase < MiniTest::Assertions - include ForMiniTest - else - include ForClassicTestUnit - end + included do + include ActiveSupport::Callbacks + define_callbacks :setup, :teardown + + if defined?(MiniTest::Assertions) && TestCase < MiniTest::Assertions + include ForMiniTest + else + include ForClassicTestUnit + end + end + + module ClassMethods + def setup(*args, &block) + set_callback(:setup, :before, *args, &block) + end + + def teardown(*args, &block) + set_callback(:teardown, :after, *args, &block) end end @@ -18,13 +28,14 @@ module ActiveSupport def run(runner) result = '.' begin - run_callbacks :setup - result = super + _run_setup_callbacks do + result = super + end rescue Exception => e result = runner.puke(self.class, method_name, e) ensure begin - run_callbacks :teardown, :enumerator => :reverse_each + _run_teardown_callbacks rescue Exception => e result = runner.puke(self.class, method_name, e) end @@ -42,23 +53,17 @@ module ActiveSupport def run(result) return if @method_name.to_s == "default_test" - if using_mocha = respond_to?(:mocha_verify) - assertion_counter_klass = if defined?(Mocha::TestCaseAdapter::AssertionCounter) - Mocha::TestCaseAdapter::AssertionCounter - else - Mocha::Integration::TestUnit::AssertionCounter - end - assertion_counter = assertion_counter_klass.new(result) - end - + mocha_counter = retrieve_mocha_counter(result) yield(Test::Unit::TestCase::STARTED, name) @_result = result + begin begin - run_callbacks :setup - setup - __send__(@method_name) - mocha_verify(assertion_counter) if using_mocha + _run_setup_callbacks do + setup + __send__(@method_name) + mocha_verify(mocha_counter) if mocha_counter + end rescue Mocha::ExpectationError => e add_failure(e.message, e.backtrace) rescue Test::Unit::AssertionFailedError => e @@ -69,7 +74,7 @@ module ActiveSupport ensure begin teardown - run_callbacks :teardown, :enumerator => :reverse_each + _run_teardown_callbacks rescue Test::Unit::AssertionFailedError => e add_failure(e.message, e.backtrace) rescue Exception => e @@ -78,12 +83,26 @@ module ActiveSupport end end ensure - mocha_teardown if using_mocha + mocha_teardown if mocha_counter end + result.add_run yield(Test::Unit::TestCase::FINISHED, name) end + + protected + + def retrieve_mocha_counter(result) #:nodoc: + if using_mocha = respond_to?(:mocha_verify) + if defined?(Mocha::TestCaseAdapter::AssertionCounter) + Mocha::TestCaseAdapter::AssertionCounter.new(result) + else + Mocha::Integration::TestUnit::AssertionCounter.new(result) + end + end + end end + end end end diff --git a/activesupport/test/isolation_test.rb b/activesupport/test/isolation_test.rb index 20e11df1dd..39c2166016 100644 --- a/activesupport/test/isolation_test.rb +++ b/activesupport/test/isolation_test.rb @@ -1,162 +1,182 @@ require 'abstract_unit' require 'rbconfig' -if defined?(MiniTest) || defined?(Test::Unit::TestResultFailureSupport) - $stderr.puts "Isolation tests can test test-unit 1 only" +# if defined?(MiniTest) || defined?(Test::Unit::TestResultFailureSupport) +# $stderr.puts "Isolation tests can test test-unit 1 only" -else - # Does awesome - if ENV['CHILD'] - class ChildIsolationTest < ActiveSupport::TestCase - include ActiveSupport::Testing::Isolation - - def self.setup - File.open(File.join(File.dirname(__FILE__), "fixtures", "isolation_test"), "a") do |f| - f.puts "hello" - end - end +if ENV['CHILD'] + class ChildIsolationTest < ActiveSupport::TestCase + include ActiveSupport::Testing::Isolation - def setup - @instance = "HELLO" + def self.setup + File.open(File.join(File.dirname(__FILE__), "fixtures", "isolation_test"), "a") do |f| + f.puts "hello" end + end - def teardown - raise if @boom - end + def setup + @instance = "HELLO" + end - test "runs the test" do - assert true - end + def teardown + raise if @boom + end - test "captures errors" do - raise - end + test "runs the test" do + assert true + end - test "captures failures" do - assert false - end + test "captures errors" do + raise + end - test "first runs in isolation" do - assert_nil $x - $x = 1 - end + test "captures failures" do + assert false + end - test "second runs in isolation" do - assert_nil $x - $x = 2 - end + test "first runs in isolation" do + assert_nil $x + $x = 1 + end - test "runs with slow tests" do - sleep 0.3 - assert true - sleep 0.2 - end + test "second runs in isolation" do + assert_nil $x + $x = 2 + end - test "runs setup" do - assert "HELLO", @instance - end + test "runs with slow tests" do + sleep 0.3 + assert true + sleep 0.2 + end - test "runs teardown" do - @boom = true - end + test "runs setup" do + assert "HELLO", @instance + end - test "resets requires one" do - assert !defined?(OmgOmg) - assert_equal 0, $LOADED_FEATURES.grep(/fixtures\/omgomg/).size - require File.expand_path(File.join(File.dirname(__FILE__), "fixtures", "omgomg")) - end + test "runs teardown" do + @boom = true + end - test "resets requires two" do - assert !defined?(OmgOmg) - assert_equal 0, $LOADED_FEATURES.grep(/fixtures\/omgomg/).size - require File.expand_path(File.join(File.dirname(__FILE__), "fixtures", "omgomg")) - end + test "resets requires one" do + assert !defined?(OmgOmg) + assert_equal 0, $LOADED_FEATURES.grep(/fixtures\/omgomg/).size + require File.expand_path(File.join(File.dirname(__FILE__), "fixtures", "omgomg")) end - else - class ParentIsolationTest < ActiveSupport::TestCase - - File.open(File.join(File.dirname(__FILE__), "fixtures", "isolation_test"), "w") {} - - ENV["CHILD"] = "1" - OUTPUT = `#{RbConfig::CONFIG["bindir"]}/#{RbConfig::CONFIG["ruby_install_name"]} -I#{File.dirname(__FILE__)} "#{File.expand_path(__FILE__)}" -v` - ENV.delete("CHILD") - - def setup - # Extract the results - @results = {} - OUTPUT[/Started\n\s*(.*)\s*\nFinished/mi, 1].to_s.split(/\s*\n\s*/).each do |result| - result =~ %r'^(\w+)\(\w+\):\s*(\.|E|F)$' - @results[$1] = { 'E' => :error, '.' => :success, 'F' => :failure }[$2] - end - - # Extract the backtraces - @backtraces = {} - OUTPUT.scan(/^\s*\d+\).*?\n\n/m).each do |backtrace| - # \n 1) Error:\ntest_captures_errors(ChildIsolationTest): - backtrace =~ %r'\s*\d+\)\s*(Error|Failure):\n(\w+)'i - @backtraces[$2] = { :type => $1, :output => backtrace } - end - end - def assert_failing(name) - assert_equal :failure, @results[name.to_s], "Test #{name} did not fail" - end + test "resets requires two" do + assert !defined?(OmgOmg) + assert_equal 0, $LOADED_FEATURES.grep(/fixtures\/omgomg/).size + require File.expand_path(File.join(File.dirname(__FILE__), "fixtures", "omgomg")) + end + end +else + class ParentIsolationTest < ActiveSupport::TestCase - def assert_passing(name) - assert_equal :success, @results[name.to_s], "Test #{name} did not pass" - end + File.open(File.join(File.dirname(__FILE__), "fixtures", "isolation_test"), "w") {} - def assert_erroring(name) - assert_equal :error, @results[name.to_s], "Test #{name} did not error" - end + ENV["CHILD"] = "1" + OUTPUT = `#{RbConfig::CONFIG["bindir"]}/#{RbConfig::CONFIG["ruby_install_name"]} -I#{File.dirname(__FILE__)} "#{File.expand_path(__FILE__)}" -v` + ENV.delete("CHILD") - test "has all tests" do - assert_equal 10, @results.length - end + def setup + defined?(::MiniTest) ? parse_minitest : parse_testunit + end - test "passing tests are still reported" do - assert_passing :test_runs_the_test - assert_passing :test_runs_with_slow_tests + def parse_testunit + @results = {} + OUTPUT[/Started\n\s*(.*)\s*\nFinished/mi, 1].to_s.split(/\s*\n\s*/).each do |result| + result =~ %r'^(\w+)\(\w+\):\s*(\.|E|F)$' + @results[$1] = { 'E' => :error, '.' => :success, 'F' => :failure }[$2] end - test "resets global variables" do - assert_passing :test_first_runs_in_isolation - assert_passing :test_second_runs_in_isolation + # Extract the backtraces + @backtraces = {} + OUTPUT.scan(/^\s*\d+\).*?\n\n/m).each do |backtrace| + # \n 1) Error:\ntest_captures_errors(ChildIsolationTest): + backtrace =~ %r'\s*\d+\)\s*(Error|Failure):\n(\w+)'i + @backtraces[$2] = { :type => $1, :output => backtrace } end + end - test "resets requires" do - assert_passing :test_resets_requires_one - assert_passing :test_resets_requires_two - end + def parse_minitest + @results = {} + OUTPUT[/Started\n\s*(.*)\s*\nFinished/mi, 1].to_s.split(/\s*\n\s*/).each do |result| + result =~ %r'^\w+#(\w+):.*:\s*(.*Assertion.*|.*RuntimeError.*|\.\s*)$' + val = :success + val = :error if $2.include?('RuntimeError') + val = :failure if $2.include?('Assertion') - test "erroring tests are still reported" do - assert_erroring :test_captures_errors + @results[$1] = val end - test "runs setup and teardown methods" do - assert_passing :test_runs_setup - assert_erroring :test_runs_teardown + # Extract the backtraces + @backtraces = {} + OUTPUT.scan(/^\s*\d+\).*?\n\n/m).each do |backtrace| + # \n 1) Error:\ntest_captures_errors(ChildIsolationTest): + backtrace =~ %r'\s*\d+\)\s*(Error|Failure):\n(\w+)'i + @backtraces[$2] = { :type => $1, :output => backtrace } end + end - test "correct tests fail" do - assert_failing :test_captures_failures - end + def assert_failing(name) + assert_equal :failure, @results[name.to_s], "Test #{name} failed" + end - test "backtrace is printed for errors" do - assert_equal 'Error', @backtraces["test_captures_errors"][:type] - assert_match %r{isolation_test.rb:\d+:in `test_captures_errors'}, @backtraces["test_captures_errors"][:output] - end + def assert_passing(name) + assert_equal :success, @results[name.to_s], "Test #{name} passed" + end - test "backtrace is printed for failures" do - assert_equal 'Failure', @backtraces["test_captures_failures"][:type] - assert_match %r{isolation_test.rb:\d+:in `test_captures_failures'}, @backtraces["test_captures_failures"][:output] - end + def assert_erroring(name) + assert_equal :error, @results[name.to_s], "Test #{name} errored" + end - test "self.setup is run only once" do - text = File.read(File.join(File.dirname(__FILE__), "fixtures", "isolation_test")) - assert_equal "hello\n", text - end + test "has all tests" do + assert_equal 10, @results.length + end + + test "passing tests are still reported" do + assert_passing :test_runs_the_test + assert_passing :test_runs_with_slow_tests + end + test "resets global variables" do + assert_passing :test_first_runs_in_isolation + assert_passing :test_second_runs_in_isolation end + + test "resets requires" do + assert_passing :test_resets_requires_one + assert_passing :test_resets_requires_two + end + + test "erroring tests are still reported" do + assert_erroring :test_captures_errors + end + + test "runs setup and teardown methods" do + assert_passing :test_runs_setup + assert_erroring :test_runs_teardown + end + + test "correct tests fail" do + assert_failing :test_captures_failures + end + + test "backtrace is printed for errors" do + assert_equal 'Error', @backtraces["test_captures_errors"][:type] + assert_match %r{isolation_test.rb:\d+}, @backtraces["test_captures_errors"][:output] + end + + test "backtrace is printed for failures" do + assert_equal 'Failure', @backtraces["test_captures_failures"][:type] + assert_match %r{isolation_test.rb:\d+}, @backtraces["test_captures_failures"][:output] + end + + test "self.setup is run only once" do + text = File.read(File.join(File.dirname(__FILE__), "fixtures", "isolation_test")) + assert_equal "hello\n", text + end + end end diff --git a/activesupport/test/test_test.rb b/activesupport/test/test_test.rb index 5cbffb81fc..1928da51ca 100644 --- a/activesupport/test/test_test.rb +++ b/activesupport/test/test_test.rb @@ -102,9 +102,9 @@ class SetupAndTeardownTest < ActiveSupport::TestCase teardown :foo, :sentinel, :foo def test_inherited_setup_callbacks - assert_equal [:reset_callback_record, :foo], self.class.setup_callback_chain.map(&:method) + assert_equal [:reset_callback_record, :foo], self.class._setup_callbacks.map(&:raw_filter) assert_equal [:foo], @called_back - assert_equal [:foo, :sentinel, :foo], self.class.teardown_callback_chain.map(&:method) + assert_equal [:foo, :sentinel, :foo], self.class._teardown_callbacks.map(&:raw_filter) end def setup @@ -114,6 +114,7 @@ class SetupAndTeardownTest < ActiveSupport::TestCase end protected + def reset_callback_record @called_back = [] end @@ -133,9 +134,9 @@ class SubclassSetupAndTeardownTest < SetupAndTeardownTest teardown :bar def test_inherited_setup_callbacks - assert_equal [:reset_callback_record, :foo, :bar], self.class.setup_callback_chain.map(&:method) + assert_equal [:reset_callback_record, :foo, :bar], self.class._setup_callbacks.map(&:raw_filter) assert_equal [:foo, :bar], @called_back - assert_equal [:foo, :sentinel, :foo, :bar], self.class.teardown_callback_chain.map(&:method) + assert_equal [:foo, :sentinel, :foo, :bar], self.class._teardown_callbacks.map(&:raw_filter) end protected diff --git a/railties/lib/rails/configuration.rb b/railties/lib/rails/configuration.rb index cb321536d2..086f67a419 100644 --- a/railties/lib/rails/configuration.rb +++ b/railties/lib/rails/configuration.rb @@ -1,24 +1,6 @@ require 'active_support/ordered_options' module Rails - # Create a Plugin::Options from ActiveSuppot::OrderedOptions, - # which support the following syntax: - # - # controller.action_controller.include FooBar - # - class Plugin::Options < ActiveSupport::OrderedOptions #:nodoc: - attr_reader :includes - - def initialize(*args) - @includes = [] - super - end - - def include(*args) - @includes.concat(args) - end - end - # Temporarily separate the plugin configuration class from the main # configuration class while this bit is being cleaned up. class Plugin::Configuration @@ -34,7 +16,7 @@ module Rails @options = base.options.dup @middleware = base.middleware.dup else - @options = Hash.new { |h,k| h[k] = Rails::Plugin::Options.new } + @options = Hash.new { |h,k| h[k] = ActiveSupport::OrderedOptions.new } @middleware = ActionDispatch::MiddlewareStack.new end end diff --git a/railties/lib/rails/core.rb b/railties/lib/rails/core.rb index c819e90dd7..ab95edc676 100644 --- a/railties/lib/rails/core.rb +++ b/railties/lib/rails/core.rb @@ -12,7 +12,6 @@ require 'rails/railties_path' require 'rails/version' require 'rails/rack' require 'rails/paths' -require 'rails/core' require 'rails/configuration' require 'rails/deprecation' require 'rails/ruby_version_check' @@ -103,4 +102,4 @@ module Rails @@public_path = path end end -end
\ No newline at end of file +end diff --git a/railties/lib/rails/plugin.rb b/railties/lib/rails/plugin.rb index c64042cf7d..e154e9b706 100644 --- a/railties/lib/rails/plugin.rb +++ b/railties/lib/rails/plugin.rb @@ -40,24 +40,6 @@ module Rails rake_tasks.each { |blk| blk.call } end - # Creates an initializer which includes all given modules to the given class. - # - # module Rails - # class ActionController < Rails::Plugin - # plugin_name :action_controller - # include_modules_in "ActionController::Base" - # end - # end - # - def self.include_modules_in(klass, from=plugin_name) - self.initializer :"#{from}.include_modules" do |app| - klass = klass.constantize if klass.is_a?(String) - app.config.send(from).includes.each do |mod| - klass.send(:include, mod.is_a?(String) ? mod.constantize : mod) - end - end - end - class Vendored < Plugin def self.all(list, paths) plugins = [] @@ -121,4 +103,4 @@ module Rails end end end -end
\ No newline at end of file +end diff --git a/railties/test/plugins/configuration_test.rb b/railties/test/plugins/configuration_test.rb index 0843d05577..5786316d1d 100644 --- a/railties/test/plugins/configuration_test.rb +++ b/railties/test/plugins/configuration_test.rb @@ -8,10 +8,6 @@ module PluginsTest require "rails" end - module Bar; end - module Baz; end - module All; end - test "config is available to plugins" do class Foo < Rails::Plugin ; end assert_nil Foo.config.action_controller.foo @@ -28,18 +24,6 @@ module PluginsTest assert_equal "hello", AppTemplate::Application.config.foo.greetings end - test "plugin configurations allow modules to be given" do - class Foo < Rails::Plugin ; config.foo.include(Bar, Baz) ; end - assert_equal [Bar, Baz], Foo.config.foo.includes - end - - test "plugin includes given modules in given class" do - class Foo < Rails::Plugin ; config.foo.include(Bar, "PluginsTest::ConfigurationTest::Baz") ; include_modules_in All ; end - Foo.new.run_initializers(Foo) - assert All.ancestors.include?(Bar) - assert All.ancestors.include?(Baz) - end - test "plugin config merges are deep" do class Foo < Rails::Plugin ; config.foo.greetings = 'hello' ; end class MyApp < Rails::Application |