aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
authorXavier Noria <fxn@hashref.com>2010-06-20 23:13:19 +0200
committerXavier Noria <fxn@hashref.com>2010-06-20 23:13:19 +0200
commit207fa59675cb624dde0e01c1d57597f752cdf095 (patch)
tree472d03af5bc3e2df1b759717f723ca914f2a77aa /activesupport
parent31cadc730a40281950a265ff6982dd76cc326828 (diff)
parent50d37a76064239a731f81a4ba68b80946c4dfae2 (diff)
downloadrails-207fa59675cb624dde0e01c1d57597f752cdf095.tar.gz
rails-207fa59675cb624dde0e01c1d57597f752cdf095.tar.bz2
rails-207fa59675cb624dde0e01c1d57597f752cdf095.zip
Merge remote branch 'rails/master'
Conflicts: actionpack/lib/abstract_controller/base.rb
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/CHANGELOG4
-rw-r--r--activesupport/Rakefile4
-rw-r--r--[-rwxr-xr-x]activesupport/bin/generate_tables0
-rw-r--r--activesupport/lib/active_support.rb3
-rw-r--r--activesupport/lib/active_support/callbacks.rb10
-rw-r--r--activesupport/lib/active_support/core_ext/class/subclasses.rb10
-rw-r--r--activesupport/lib/active_support/core_ext/date_time/zones.rb2
-rw-r--r--[-rwxr-xr-x]activesupport/lib/active_support/core_ext/object/to_param.rb0
-rw-r--r--activesupport/lib/active_support/core_ext/time/zones.rb2
-rw-r--r--activesupport/lib/active_support/descendants_tracker.rb39
-rw-r--r--activesupport/lib/active_support/file_update_checker.rb37
-rw-r--r--activesupport/lib/active_support/i18n.rb1
-rw-r--r--activesupport/lib/active_support/i18n_railtie.rb80
-rw-r--r--activesupport/lib/active_support/json/backends/yajl.rb2
-rw-r--r--activesupport/lib/active_support/multibyte/chars.rb34
-rw-r--r--activesupport/lib/active_support/railtie.rb72
-rw-r--r--activesupport/lib/active_support/testing/performance.rb122
-rw-r--r--activesupport/test/core_ext/time_with_zone_test.rb7
-rw-r--r--activesupport/test/descendants_tracker_test.rb75
-rw-r--r--activesupport/test/file_update_checker_test.rb56
-rw-r--r--activesupport/test/multibyte_chars_test.rb14
21 files changed, 410 insertions, 164 deletions
diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG
index 13ec3c3775..abd0664118 100644
--- a/activesupport/CHANGELOG
+++ b/activesupport/CHANGELOG
@@ -1,5 +1,9 @@
*Rails 3.0.0 [Release Candidate] (unreleased)*
+* Added ActiveSupport::FileUpdateChecker to execute a block only if a set of files changed, used by Router and I18n locale files. [José Valim]
+
+* Added ActiveSupport::DescendantsTracker to track descendants with support to constants reloading. [José Valim]
+
* ActiveSupport::OrderedHash#merge and #merge! accept a block. #4838 [Paul Mucur, fxn]
* Date#since, #ago, #beginning_of_day, #end_of_day, and #xmlschema honor now the user time zone if set. [Geoff Buesing]
diff --git a/activesupport/Rakefile b/activesupport/Rakefile
index 43f4722dbc..2aebe05de2 100644
--- a/activesupport/Rakefile
+++ b/activesupport/Rakefile
@@ -1,3 +1,5 @@
+gem 'rdoc', '= 2.2'
+require 'rdoc'
require 'rake/testtask'
require 'rake/rdoctask'
require 'rake/gempackagetask'
@@ -47,5 +49,5 @@ end
desc "Publish the API documentation"
task :pdoc => [:rdoc] do
require 'rake/contrib/sshpublisher'
- Rake::SshDirPublisher.new("wrath.rubyonrails.org", "public_html/as", "doc").upload
+ Rake::SshDirPublisher.new("rails@api.rubyonrails.org", "public_html/as", "doc").upload
end
diff --git a/activesupport/bin/generate_tables b/activesupport/bin/generate_tables
index 51edb59c77..51edb59c77 100755..100644
--- a/activesupport/bin/generate_tables
+++ b/activesupport/bin/generate_tables
diff --git a/activesupport/lib/active_support.rb b/activesupport/lib/active_support.rb
index e34e46b4cf..3ce5476bbd 100644
--- a/activesupport/lib/active_support.rb
+++ b/activesupport/lib/active_support.rb
@@ -39,6 +39,9 @@ require "active_support/dependencies/autoload"
module ActiveSupport
extend ActiveSupport::Autoload
+ autoload :DescendantsTracker
+ autoload :FileUpdateChecker
+
# TODO: Narrow this list down
eager_autoload do
autoload :BacktraceCleaner
diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb
index 3ff33eea72..c4e1eb2c04 100644
--- a/activesupport/lib/active_support/callbacks.rb
+++ b/activesupport/lib/active_support/callbacks.rb
@@ -1,6 +1,6 @@
+require 'active_support/descendants_tracker'
require 'active_support/core_ext/array/wrap'
require 'active_support/core_ext/class/inheritable_attributes'
-require 'active_support/core_ext/class/subclasses'
require 'active_support/core_ext/kernel/reporting'
require 'active_support/core_ext/kernel/singleton_class'
@@ -85,6 +85,10 @@ module ActiveSupport
module Callbacks
extend Concern
+ included do
+ extend ActiveSupport::DescendantsTracker
+ end
+
def run_callbacks(kind, *args, &block)
send("_run_#{kind}_callbacks", *args, &block)
end
@@ -428,7 +432,7 @@ module ActiveSupport
options = filters.last.is_a?(Hash) ? filters.pop : {}
filters.unshift(block) if block
- ([self] + self.descendents).each do |target|
+ ([self] + self.descendants).each do |target|
chain = target.send("_#{name}_callbacks")
yield chain, type, filters, options
target.__define_runner(name)
@@ -502,7 +506,7 @@ module ActiveSupport
def reset_callbacks(symbol)
callbacks = send("_#{symbol}_callbacks")
- self.descendents.each do |target|
+ self.descendants.each do |target|
chain = target.send("_#{symbol}_callbacks")
callbacks.each { |c| chain.delete(c) }
target.__define_runner(symbol)
diff --git a/activesupport/lib/active_support/core_ext/class/subclasses.rb b/activesupport/lib/active_support/core_ext/class/subclasses.rb
index bbd8f5aef6..7d58a8b56a 100644
--- a/activesupport/lib/active_support/core_ext/class/subclasses.rb
+++ b/activesupport/lib/active_support/core_ext/class/subclasses.rb
@@ -11,9 +11,9 @@ class Class #:nodoc:
# Rubinius
if defined?(Class.__subclasses__)
- def descendents
+ def descendants
subclasses = []
- __subclasses__.each {|k| subclasses << k; subclasses.concat k.descendents }
+ __subclasses__.each {|k| subclasses << k; subclasses.concat k.descendants }
subclasses
end
else
@@ -21,7 +21,7 @@ class Class #:nodoc:
begin
ObjectSpace.each_object(Class.new) {}
- def descendents
+ def descendants
subclasses = []
ObjectSpace.each_object(class << self; self; end) do |k|
subclasses << k unless k == self
@@ -30,7 +30,7 @@ class Class #:nodoc:
end
# JRuby
rescue StandardError
- def descendents
+ def descendants
subclasses = []
ObjectSpace.each_object(Class) do |k|
subclasses << k if k < self
@@ -48,7 +48,7 @@ class Class #:nodoc:
def self.subclasses_of(*superclasses) #:nodoc:
subclasses = []
superclasses.each do |klass|
- subclasses.concat klass.descendents.select {|k| k.anonymous? || k.reachable?}
+ subclasses.concat klass.descendants.select {|k| k.anonymous? || k.reachable?}
end
subclasses
end
diff --git a/activesupport/lib/active_support/core_ext/date_time/zones.rb b/activesupport/lib/active_support/core_ext/date_time/zones.rb
index 98565e6750..6002d4ad2a 100644
--- a/activesupport/lib/active_support/core_ext/date_time/zones.rb
+++ b/activesupport/lib/active_support/core_ext/date_time/zones.rb
@@ -12,6 +12,8 @@ class DateTime
#
# DateTime.new(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
def in_time_zone(zone = ::Time.zone)
+ return self unless zone
+
ActiveSupport::TimeWithZone.new(utc? ? self : getutc, ::Time.__send__(:get_zone, zone))
end
end
diff --git a/activesupport/lib/active_support/core_ext/object/to_param.rb b/activesupport/lib/active_support/core_ext/object/to_param.rb
index 06f077e920..06f077e920 100755..100644
--- a/activesupport/lib/active_support/core_ext/object/to_param.rb
+++ b/activesupport/lib/active_support/core_ext/object/to_param.rb
diff --git a/activesupport/lib/active_support/core_ext/time/zones.rb b/activesupport/lib/active_support/core_ext/time/zones.rb
index adc9fe3824..a02402aa3f 100644
--- a/activesupport/lib/active_support/core_ext/time/zones.rb
+++ b/activesupport/lib/active_support/core_ext/time/zones.rb
@@ -73,6 +73,8 @@ class Time
#
# Time.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
def in_time_zone(zone = ::Time.zone)
+ return self unless zone
+
ActiveSupport::TimeWithZone.new(utc? ? self : getutc, ::Time.__send__(:get_zone, zone))
end
end
diff --git a/activesupport/lib/active_support/descendants_tracker.rb b/activesupport/lib/active_support/descendants_tracker.rb
new file mode 100644
index 0000000000..a587d7770c
--- /dev/null
+++ b/activesupport/lib/active_support/descendants_tracker.rb
@@ -0,0 +1,39 @@
+require 'active_support/dependencies'
+
+module ActiveSupport
+ # This module provides an internal implementation to track descendants
+ # which is faster than iterating through ObjectSpace.
+ module DescendantsTracker
+ @@descendants = Hash.new { |h, k| h[k] = [] }
+
+ def self.descendants
+ @@descendants
+ end
+
+ def self.clear
+ @@descendants.each do |klass, descendants|
+ if ActiveSupport::Dependencies.autoloaded?(klass)
+ @@descendants.delete(klass)
+ else
+ descendants.reject! { |v| ActiveSupport::Dependencies.autoloaded?(v) }
+ end
+ end
+ end
+
+ def inherited(base)
+ self.direct_descendants << base
+ super
+ end
+
+ def direct_descendants
+ @@descendants[self]
+ end
+
+ def descendants
+ @@descendants[self].inject([]) do |descendants, klass|
+ descendants << klass
+ descendants.concat klass.descendants
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/activesupport/lib/active_support/file_update_checker.rb b/activesupport/lib/active_support/file_update_checker.rb
new file mode 100644
index 0000000000..c0b5ca4deb
--- /dev/null
+++ b/activesupport/lib/active_support/file_update_checker.rb
@@ -0,0 +1,37 @@
+module ActiveSupport
+ # This class is responsible to track files and invoke the given block
+ # whenever one of these files are changed. For example, this class
+ # is used by Rails to reload routes whenever they are changed upon
+ # a new request.
+ #
+ # routes_reloader = ActiveSupport::FileUpdateChecker.new(paths) do
+ # paths.each { |p| load(p) }
+ # Rails::Application.routes.reload!
+ # end
+ #
+ # ActionDispatch::Callbacks.to_prepare do
+ # routes_reloader.execute_if_updated
+ # end
+ #
+ class FileUpdateChecker
+ attr_reader :paths, :last_update_at
+
+ def initialize(paths, calculate=false, &block)
+ @paths = paths
+ @block = block
+ @last_update_at = updated_at if calculate
+ end
+
+ def updated_at
+ paths.map { |path| File.stat(path).mtime }.max
+ end
+
+ def execute_if_updated
+ current_update_at = self.updated_at
+ if @last_update_at != current_update_at
+ @last_update_at = current_update_at
+ @block.call
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/activesupport/lib/active_support/i18n.rb b/activesupport/lib/active_support/i18n.rb
index 0ffdd904fd..45b9d20c01 100644
--- a/activesupport/lib/active_support/i18n.rb
+++ b/activesupport/lib/active_support/i18n.rb
@@ -4,5 +4,6 @@ rescue LoadError => e
$stderr.puts "You don't have i18n installed in your application. Please add it to your Gemfile and run bundle install"
raise e
end
+
I18n.load_path << "#{File.dirname(__FILE__)}/locale/en.yml"
ActiveSupport.run_load_hooks(:i18n)
diff --git a/activesupport/lib/active_support/i18n_railtie.rb b/activesupport/lib/active_support/i18n_railtie.rb
new file mode 100644
index 0000000000..d82e54f1d4
--- /dev/null
+++ b/activesupport/lib/active_support/i18n_railtie.rb
@@ -0,0 +1,80 @@
+require "active_support"
+require "rails"
+require "active_support/file_update_checker"
+
+module I18n
+ class Railtie < Rails::Railtie
+ config.i18n = ActiveSupport::OrderedOptions.new
+ config.i18n.railties_load_path = []
+ config.i18n.load_path = []
+ config.i18n.fallbacks = ActiveSupport::OrderedOptions.new
+
+ def self.reloader
+ @reloader ||= ActiveSupport::FileUpdateChecker.new([]){ I18n.reload! }
+ end
+
+ # Add I18n::Railtie.reloader to ActionDispatch callbacks. Since, at this
+ # point, no path was added to the reloader, I18n.reload! is not triggered
+ # on to_prepare callbacks. This will only happen on the config.after_initialize
+ # callback below.
+ initializer "i18n.callbacks" do
+ ActionDispatch::Callbacks.to_prepare do
+ I18n::Railtie.reloader.execute_if_updated
+ end
+ end
+
+ # Set the i18n configuration only after initialization since a lot of
+ # configuration is still usually done in application initializers.
+ config.after_initialize do |app|
+ fallbacks = app.config.i18n.delete(:fallbacks)
+
+ app.config.i18n.each do |setting, value|
+ case setting
+ when :railties_load_path
+ app.config.i18n.load_path.unshift(*value)
+ when :load_path
+ I18n.load_path += value
+ else
+ I18n.send("#{setting}=", value)
+ end
+ end
+
+ init_fallbacks(fallbacks) if fallbacks && validate_fallbacks(fallbacks)
+
+ reloader.paths.concat I18n.load_path
+ reloader.execute_if_updated
+ end
+
+ protected
+
+ def self.include_fallbacks_module
+ I18n.backend.class.send(:include, I18n::Backend::Fallbacks)
+ end
+
+ def self.init_fallbacks(fallbacks)
+ include_fallbacks_module
+
+ args = case fallbacks
+ when ActiveSupport::OrderedOptions
+ [*(fallbacks[:defaults] || []) << fallbacks[:map]].compact
+ when Hash, Array
+ Array.wrap(fallbacks)
+ else # TrueClass
+ []
+ end
+
+ I18n.fallbacks = I18n::Locale::Fallbacks.new(*args)
+ end
+
+ def self.validate_fallbacks(fallbacks)
+ case fallbacks
+ when ActiveSupport::OrderedOptions
+ !fallbacks.empty?
+ when TrueClass, Array, Hash
+ true
+ else
+ raise "Unexpected fallback type #{fallbacks.inspect}"
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/activesupport/lib/active_support/json/backends/yajl.rb b/activesupport/lib/active_support/json/backends/yajl.rb
index d76f8b03e4..64e50e0d87 100644
--- a/activesupport/lib/active_support/json/backends/yajl.rb
+++ b/activesupport/lib/active_support/json/backends/yajl.rb
@@ -1,4 +1,4 @@
-require 'yajl-ruby' unless defined?(Yajl)
+require 'yajl' unless defined?(Yajl)
module ActiveSupport
module JSON
diff --git a/activesupport/lib/active_support/multibyte/chars.rb b/activesupport/lib/active_support/multibyte/chars.rb
index d6ccb4bac1..04193bfa65 100644
--- a/activesupport/lib/active_support/multibyte/chars.rb
+++ b/activesupport/lib/active_support/multibyte/chars.rb
@@ -50,10 +50,6 @@ module ActiveSupport #:nodoc:
end
end
- def <=>(other)
- @wrapped_string <=> other
- end
-
# Forward all undefined methods to the wrapped string.
def method_missing(method, *args, &block)
if method.to_s =~ /!$/
@@ -87,6 +83,16 @@ module ActiveSupport #:nodoc:
include Comparable
+ # Returns <tt>-1</tt>, <tt>0</tt> or <tt>+1</tt> depending on whether the Chars object is to be sorted before,
+ # equal or after the object on the right side of the operation. It accepts any object that implements +to_s+.
+ # See <tt>String#<=></tt> for more details.
+ #
+ # Example:
+ # 'é'.mb_chars <=> 'ü'.mb_chars #=> -1
+ def <=>(other)
+ @wrapped_string <=> other.to_s
+ end
+
if RUBY_VERSION < "1.9"
# Returns +true+ if the Chars class can and should act as a proxy for the string _string_. Returns
# +false+ otherwise.
@@ -94,16 +100,6 @@ module ActiveSupport #:nodoc:
$KCODE == 'UTF8' && consumes?(string)
end
- # Returns <tt>-1</tt>, <tt>0</tt> or <tt>+1</tt> depending on whether the Chars object is to be sorted before,
- # equal or after the object on the right side of the operation. It accepts any object that implements +to_s+.
- # See <tt>String#<=></tt> for more details.
- #
- # Example:
- # 'é'.mb_chars <=> 'ü'.mb_chars #=> -1
- def <=>(other)
- @wrapped_string <=> other.to_s
- end
-
# Returns a new Chars object containing the _other_ object concatenated to the string.
#
# Example:
@@ -375,6 +371,16 @@ module ActiveSupport #:nodoc:
(slice(0) || chars('')).upcase + (slice(1..-1) || chars('')).downcase
end
+ # Capitalizes the first letter of every word, when possible.
+ #
+ # Example:
+ # "ÉL QUE SE ENTERÓ".mb_chars.titleize # => "Él Que Se Enteró"
+ # "日本語".mb_chars.titleize # => "日本語"
+ def titleize
+ chars(downcase.to_s.gsub(/\b('?[\S])/u) { Unicode.apply_mapping $1, :uppercase_mapping })
+ end
+ alias_method :titlecase, :titleize
+
# Returns the KC normalization of the string by default. NFKC is considered the best normalization form for
# passing strings to databases and validations.
#
diff --git a/activesupport/lib/active_support/railtie.rb b/activesupport/lib/active_support/railtie.rb
index 59f9ab18b1..1f32f8718f 100644
--- a/activesupport/lib/active_support/railtie.rb
+++ b/activesupport/lib/active_support/railtie.rb
@@ -1,5 +1,6 @@
require "active_support"
require "rails"
+require "active_support/i18n_railtie"
module ActiveSupport
class Railtie < Rails::Railtie
@@ -26,75 +27,4 @@ module ActiveSupport
Time.zone_default = zone_default
end
end
-end
-
-module I18n
- class Railtie < Rails::Railtie
- config.i18n = ActiveSupport::OrderedOptions.new
- config.i18n.railties_load_path = []
- config.i18n.load_path = []
- config.i18n.fallbacks = ActiveSupport::OrderedOptions.new
-
- initializer "i18n.initialize" do
- ActiveSupport.on_load(:i18n) do
- I18n.reload!
-
- ActionDispatch::Callbacks.to_prepare do
- I18n.reload!
- end
- end
- end
-
- # Set the i18n configuration from config.i18n but special-case for
- # the load_path which should be appended to what's already set instead of overwritten.
- config.after_initialize do |app|
- fallbacks = app.config.i18n.delete(:fallbacks)
-
- app.config.i18n.each do |setting, value|
- case setting
- when :railties_load_path
- app.config.i18n.load_path.unshift(*value)
- when :load_path
- I18n.load_path += value
- else
- I18n.send("#{setting}=", value)
- end
- end
-
- init_fallbacks(fallbacks) if fallbacks && validate_fallbacks(fallbacks)
- I18n.reload!
- end
-
- class << self
- protected
-
- def init_fallbacks(fallbacks)
- include_fallbacks_module
- args = case fallbacks
- when ActiveSupport::OrderedOptions
- [*(fallbacks[:defaults] || []) << fallbacks[:map]].compact
- when Hash, Array
- Array.wrap(fallbacks)
- else # TrueClass
- []
- end
- I18n.fallbacks = I18n::Locale::Fallbacks.new(*args)
- end
-
- def include_fallbacks_module
- I18n.backend.class.send(:include, I18n::Backend::Fallbacks)
- end
-
- def validate_fallbacks(fallbacks)
- case fallbacks
- when ActiveSupport::OrderedOptions
- !fallbacks.empty?
- when TrueClass, Array, Hash
- true
- else
- raise "Unexpected fallback type #{fallbacks.inspect}"
- end
- end
- end
- end
end \ No newline at end of file
diff --git a/activesupport/lib/active_support/testing/performance.rb b/activesupport/lib/active_support/testing/performance.rb
index 24eea1e40b..cd628a956d 100644
--- a/activesupport/lib/active_support/testing/performance.rb
+++ b/activesupport/lib/active_support/testing/performance.rb
@@ -260,14 +260,8 @@ begin
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)
+ # Ruby 1.9 + extented GC profiler patch
+ if defined?(GC::Profiler) and GC::Profiler.respond_to?(:data)
def with_gc_stats
GC.start
GC.disable
@@ -277,6 +271,16 @@ begin
GC::Profiler.disable
GC.enable
end
+
+ # Ruby 1.8 + ruby-prof wrapper (enable/disable stats for Benchmarker)
+ elsif GC.respond_to?(:enable_stats)
+ def with_gc_stats
+ GC.enable_stats
+ yield
+ ensure
+ GC.disable_stats
+ end
+
else
def with_gc_stats
yield
@@ -319,7 +323,7 @@ begin
def initialize(*args)
# FIXME: yeah my CPU is 2.33 GHz
- RubyProf.cpu_frequency = 2.33e9
+ RubyProf.cpu_frequency = 2.33e9 unless RubyProf.cpu_frequency > 0
super
end
@@ -331,38 +335,8 @@ begin
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)
+ # Ruby 1.9 + extended GC profiler patch
+ if defined?(GC::Profiler) and GC::Profiler.respond_to?(:data)
def measure
GC.enable
GC.start
@@ -370,6 +344,12 @@ begin
GC.disable
kb
end
+
+ # Ruby 1.8 + ruby-prof wrapper
+ elsif RubyProf.respond_to?(:measure_memory)
+ def measure
+ RubyProf.measure_memory / 1024.0
+ end
end
def format(measurement)
@@ -380,27 +360,21 @@ begin
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)
+ # Ruby 1.9 + extented GC profiler patch
+ if defined?(GC::Profiler) and GC::Profiler.respond_to?(:data)
def measure
GC.enable
GC.start
- last = GC::Profiler.data.last
- count = last[:HEAP_LIVE_OBJECTS] + last[:HEAP_FREE_OBJECTS]
+ count = GC::Profiler.data.last[:HEAP_TOTAL_OBJECTS]
GC.disable
count
end
+
+ # Ruby 1.8 + ruby-prof wrapper
+ elsif RubyProf.respond_to?(:measure_allocations)
+ def measure
+ RubyProf.measure_allocations
+ end
end
def format(measurement)
@@ -411,17 +385,20 @@ begin
class GcRuns < Base
Mode = RubyProf::GC_RUNS if RubyProf.const_defined?(:GC_RUNS)
- if RubyProf.respond_to?(:measure_gc_runs)
+ # Ruby 1.9 + extented GC profiler patch
+ if defined?(GC::Profiler) and GC::Profiler.respond_to?(:data)
def measure
- RubyProf.measure_gc_runs
- end
- elsif GC.respond_to?(:collections)
- def measure
- GC.collections
+ GC.enable
+ GC.start
+ count = GC::Profiler.data.last[:GC_RUNS]
+ GC.disable
+ count
end
- elsif GC.respond_to?(:heap_info)
+
+ # Ruby 1.8 + ruby-prof wrapper
+ elsif RubyProf.respond_to?(:measure_gc_runs)
def measure
- GC.heap_info['num_gc_passes']
+ RubyProf.measure_gc_runs
end
end
@@ -433,13 +410,20 @@ begin
class GcTime < Base
Mode = RubyProf::GC_TIME if RubyProf.const_defined?(:GC_TIME)
- if RubyProf.respond_to?(:measure_gc_time)
+ # Ruby 1.9 + extented GC profiler patch
+ if defined?(GC::Profiler) and GC::Profiler.respond_to?(:data)
def measure
- RubyProf.measure_gc_time
+ GC.enable
+ GC.start
+ sec = GC::Profiler.data.inject(0) { |total, run| total += run[:GC_TIME] }
+ GC.disable
+ sec
end
- elsif GC.respond_to?(:time)
+
+ # Ruby 1.8 + ruby-prof wrapper
+ elsif RubyProf.respond_to?(:measure_gc_time)
def measure
- GC.time
+ RubyProf.measure_gc_time
end
end
@@ -452,4 +436,4 @@ begin
end
end
rescue LoadError
-end \ No newline at end of file
+end
diff --git a/activesupport/test/core_ext/time_with_zone_test.rb b/activesupport/test/core_ext/time_with_zone_test.rb
index 2cf5bd6ea9..cf11f4d28f 100644
--- a/activesupport/test/core_ext/time_with_zone_test.rb
+++ b/activesupport/test/core_ext/time_with_zone_test.rb
@@ -737,6 +737,13 @@ class TimeWithZoneMethodsForTimeAndDateTimeTest < Test::Unit::TestCase
end
end
+ def test_nil_time_zone
+ Time.use_zone nil do
+ assert !@t.in_time_zone.respond_to?(:period), 'no period method'
+ assert !@dt.in_time_zone.respond_to?(:period), 'no period method'
+ end
+ end
+
def test_in_time_zone_with_argument
Time.use_zone 'Eastern Time (US & Canada)' do # Time.zone will not affect #in_time_zone(zone)
assert_equal 'Fri, 31 Dec 1999 15:00:00 AKST -09:00', @t.in_time_zone('Alaska').inspect
diff --git a/activesupport/test/descendants_tracker_test.rb b/activesupport/test/descendants_tracker_test.rb
new file mode 100644
index 0000000000..3a424180de
--- /dev/null
+++ b/activesupport/test/descendants_tracker_test.rb
@@ -0,0 +1,75 @@
+require 'abstract_unit'
+require 'test/unit'
+require 'active_support'
+require 'active_support/core_ext/hash/slice'
+
+class DescendantsTrackerTest < Test::Unit::TestCase
+ class Parent
+ extend ActiveSupport::DescendantsTracker
+ end
+
+ class Child1 < Parent
+ end
+
+ class Child2 < Parent
+ end
+
+ class Grandchild1 < Child1
+ end
+
+ class Grandchild2 < Child1
+ end
+
+ ALL = [Parent, Child1, Child2, Grandchild1, Grandchild2]
+
+ def test_descendants
+ assert_equal [Child1, Grandchild1, Grandchild2, Child2], Parent.descendants
+ assert_equal [Grandchild1, Grandchild2], Child1.descendants
+ assert_equal [], Child2.descendants
+ end
+
+ def test_direct_descendants
+ assert_equal [Child1, Child2], Parent.direct_descendants
+ assert_equal [Grandchild1, Grandchild2], Child1.direct_descendants
+ assert_equal [], Child2.direct_descendants
+ end
+
+ def test_clear_with_autoloaded_parent_children_and_granchildren
+ mark_as_autoloaded *ALL do
+ ActiveSupport::DescendantsTracker.clear
+ assert ActiveSupport::DescendantsTracker.descendants.slice(*ALL).empty?
+ end
+ end
+
+ def test_clear_with_autoloaded_children_and_granchildren
+ mark_as_autoloaded Child1, Grandchild1, Grandchild2 do
+ ActiveSupport::DescendantsTracker.clear
+ assert_equal [Child2], Parent.descendants
+ assert_equal [], Child2.descendants
+ end
+ end
+
+ def test_clear_with_autoloaded_granchildren
+ mark_as_autoloaded Grandchild1, Grandchild2 do
+ ActiveSupport::DescendantsTracker.clear
+ assert_equal [Child1, Child2], Parent.descendants
+ assert_equal [], Child1.descendants
+ assert_equal [], Child2.descendants
+ end
+ end
+
+ protected
+
+ def mark_as_autoloaded(*klasses)
+ old_autoloaded = ActiveSupport::Dependencies.autoloaded_constants.dup
+ ActiveSupport::Dependencies.autoloaded_constants = klasses.map(&:name)
+
+ old_descendants = ActiveSupport::DescendantsTracker.descendants.dup
+ old_descendants.each { |k, v| old_descendants[k] = v.dup }
+
+ yield
+ ensure
+ ActiveSupport::Dependencies.autoloaded_constants = old_autoloaded
+ ActiveSupport::DescendantsTracker.descendants.replace(old_descendants)
+ end
+end \ No newline at end of file
diff --git a/activesupport/test/file_update_checker_test.rb b/activesupport/test/file_update_checker_test.rb
new file mode 100644
index 0000000000..baf29cc337
--- /dev/null
+++ b/activesupport/test/file_update_checker_test.rb
@@ -0,0 +1,56 @@
+require 'abstract_unit'
+require 'test/unit'
+require 'active_support'
+require 'fileutils'
+
+MTIME_FIXTURES_PATH = File.expand_path("../fixtures", __FILE__)
+
+class FileUpdateCheckerTest < Test::Unit::TestCase
+ FILES = %w(1.txt 2.txt 3.txt)
+
+ def setup
+ FileUtils.touch(FILES)
+ end
+
+ def teardown
+ FileUtils.rm(FILES)
+ end
+
+ def test_should_not_execute_the_block_if_no_paths_are_given
+ i = 0
+ checker = ActiveSupport::FileUpdateChecker.new([]){ i += 1 }
+ checker.execute_if_updated
+ assert_equal 0, i
+ end
+
+ def test_should_invoke_the_block_on_first_call_if_it_does_not_calculate_last_updated_at_on_load
+ i = 0
+ checker = ActiveSupport::FileUpdateChecker.new(FILES){ i += 1 }
+ checker.execute_if_updated
+ assert_equal 1, i
+ end
+
+ def test_should_not_invoke_the_block_on_first_call_if_it_calculates_last_updated_at_on_load
+ i = 0
+ checker = ActiveSupport::FileUpdateChecker.new(FILES, true){ i += 1 }
+ checker.execute_if_updated
+ assert_equal 0, i
+ end
+
+ def test_should_not_invoke_the_block_if_no_file_has_changed
+ i = 0
+ checker = ActiveSupport::FileUpdateChecker.new(FILES){ i += 1 }
+ 5.times { checker.execute_if_updated }
+ assert_equal 1, i
+ end
+
+ def test_should_invoke_the_block_if_a_file_has_changed
+ i = 0
+ checker = ActiveSupport::FileUpdateChecker.new(FILES){ i += 1 }
+ checker.execute_if_updated
+ sleep(1)
+ FileUtils.touch(FILES)
+ checker.execute_if_updated
+ assert_equal 2, i
+ end
+end
diff --git a/activesupport/test/multibyte_chars_test.rb b/activesupport/test/multibyte_chars_test.rb
index f7a5834527..602828ef5f 100644
--- a/activesupport/test/multibyte_chars_test.rb
+++ b/activesupport/test/multibyte_chars_test.rb
@@ -443,6 +443,11 @@ class MultibyteCharsUTF8BehaviourTest < Test::Unit::TestCase
assert_equal 'Abc', 'abc'.mb_chars.capitalize
end
+ def test_titleize_should_work_on_ascii_characters
+ assert_equal '', ''.mb_chars.titleize
+ assert_equal 'Abc Abc', 'abc abc'.mb_chars.titleize
+ end
+
def test_respond_to_knows_which_methods_the_proxy_responds_to
assert ''.mb_chars.respond_to?(:slice) # Defined on Chars
assert ''.mb_chars.respond_to?(:capitalize!) # Defined on Chars
@@ -480,6 +485,15 @@ class MultibyteCharsExtrasTest < Test::Unit::TestCase
end
end
+ def test_titleize_should_be_unicode_aware
+ assert_equal "Él Que Se Enteró", chars("ÉL QUE SE ENTERÓ").titleize
+ assert_equal "Абвг Абвг", chars("аБвг аБвг").titleize
+ end
+
+ def test_titleize_should_not_affect_characters_that_do_not_case_fold
+ assert_equal "日本語", chars("日本語").titleize
+ end
+
def test_limit_should_not_break_on_blank_strings
example = chars('')
assert_equal example, example.limit(0)