aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/README.rdoc (renamed from activesupport/README)15
-rw-r--r--activesupport/Rakefile2
-rw-r--r--activesupport/activesupport.gemspec2
-rw-r--r--activesupport/install.rb30
-rw-r--r--activesupport/lib/active_support/buffered_logger.rb6
-rw-r--r--activesupport/lib/active_support/core_ext/module/attribute_accessors.rb8
-rw-r--r--activesupport/lib/active_support/core_ext/module/remove_method.rb5
-rw-r--r--activesupport/lib/active_support/core_ext/object/to_param.rb2
-rw-r--r--activesupport/lib/active_support/log_subscriber.rb23
-rw-r--r--activesupport/lib/active_support/log_subscriber/test_helper.rb23
-rw-r--r--activesupport/lib/active_support/notifications.rb24
-rw-r--r--activesupport/lib/active_support/notifications/fanout.rb69
-rw-r--r--activesupport/lib/active_support/notifications/instrumenter.rb20
-rw-r--r--activesupport/test/buffered_logger_test.rb15
-rw-r--r--activesupport/test/core_ext/hash_ext_test.rb29
-rw-r--r--activesupport/test/multibyte_test_helpers.rb5
-rw-r--r--activesupport/test/notifications_test.rb32
17 files changed, 138 insertions, 172 deletions
diff --git a/activesupport/README b/activesupport/README.rdoc
index 9fb9a80cbe..aa86f1fd65 100644
--- a/activesupport/README
+++ b/activesupport/README.rdoc
@@ -7,22 +7,13 @@ Ruby sweeter.
== Download
-The latest version of Active Support can be found at
+The latest version of Active Support can be installed with Rubygems:
-* http://rubyforge.org/project/showfiles.php?group_id=182
+* gem install activesupport
Documentation can be found at
-* http://as.rubyonrails.com
-
-
-== Installation
-
-The preferred method of installing Active Support is through its GEM file. You'll need to have
-RubyGems[http://rubygems.rubyforge.org/wiki/wiki.pl] installed for that, though. If you have it,
-then use:
-
- % [sudo] gem install activesupport-1.0.0.gem
+* http://api.rubyonrails.org
== License
diff --git a/activesupport/Rakefile b/activesupport/Rakefile
index 2aebe05de2..77b1a8431d 100644
--- a/activesupport/Rakefile
+++ b/activesupport/Rakefile
@@ -28,7 +28,7 @@ Rake::RDocTask.new { |rdoc|
rdoc.options << '--line-numbers' << '--inline-source'
rdoc.options << '--charset' << 'utf-8'
rdoc.template = ENV['template'] ? "#{ENV['template']}.rb" : '../doc/template/horo'
- rdoc.rdoc_files.include('README', 'CHANGELOG')
+ rdoc.rdoc_files.include('README.rdoc', 'CHANGELOG')
rdoc.rdoc_files.include('lib/active_support.rb')
rdoc.rdoc_files.include('lib/active_support/**/*.rb')
}
diff --git a/activesupport/activesupport.gemspec b/activesupport/activesupport.gemspec
index 8611a1e5fa..df7f68fecf 100644
--- a/activesupport/activesupport.gemspec
+++ b/activesupport/activesupport.gemspec
@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
s.homepage = 'http://www.rubyonrails.org'
s.rubyforge_project = 'activesupport'
- s.files = Dir['CHANGELOG', 'README', 'lib/**/*']
+ s.files = Dir['CHANGELOG', 'README.rdoc', 'lib/**/*']
s.require_path = 'lib'
s.has_rdoc = true
diff --git a/activesupport/install.rb b/activesupport/install.rb
deleted file mode 100644
index 9c54d8c1a9..0000000000
--- a/activesupport/install.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-require 'rbconfig'
-require 'find'
-require 'ftools'
-
-include Config
-
-# this was adapted from rdoc's install.rb by ways of Log4r
-
-$sitedir = CONFIG["sitelibdir"]
-unless $sitedir
- version = CONFIG["MAJOR"] + "." + CONFIG["MINOR"]
- $libdir = File.join(CONFIG["libdir"], "ruby", version)
- $sitedir = $:.find {|x| x =~ /site_ruby/ }
- if !$sitedir
- $sitedir = File.join($libdir, "site_ruby")
- elsif $sitedir !~ Regexp.quote(version)
- $sitedir = File.join($sitedir, version)
- end
-end
-
-# the actual gruntwork
-Dir.chdir("lib")
-
-Find.find("active_support", "active_support.rb") { |f|
- if f[-3..-1] == ".rb"
- File::install(f, File.join($sitedir, *f.split(/\//)), 0644, true)
- else
- File::makedirs(File.join($sitedir, *f.split(/\//)))
- end
-}
diff --git a/activesupport/lib/active_support/buffered_logger.rb b/activesupport/lib/active_support/buffered_logger.rb
index 29c3843d16..b861a6f62a 100644
--- a/activesupport/lib/active_support/buffered_logger.rb
+++ b/activesupport/lib/active_support/buffered_logger.rb
@@ -101,7 +101,11 @@ module ActiveSupport
@guard.synchronize do
unless buffer.empty?
old_buffer = buffer
- @log.write(old_buffer.join)
+ all_content = StringIO.new
+ old_buffer.each do |content|
+ all_content << content
+ end
+ @log.write(all_content.string)
end
# Important to do this even if buffer was empty or else @buffer will
diff --git a/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb b/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
index 9c4d5fae26..2d88cb57e5 100644
--- a/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
+++ b/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
@@ -5,9 +5,7 @@ class Module
options = syms.extract_options!
syms.each do |sym|
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
- unless defined? @@#{sym}
- @@#{sym} = nil
- end
+ @@#{sym} = nil unless defined? @@#{sym}
def self.#{sym}
@@#{sym}
@@ -28,10 +26,6 @@ class Module
options = syms.extract_options!
syms.each do |sym|
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
- unless defined? @@#{sym}
- @@#{sym} = nil
- end
-
def self.#{sym}=(obj)
@@#{sym} = obj
end
diff --git a/activesupport/lib/active_support/core_ext/module/remove_method.rb b/activesupport/lib/active_support/core_ext/module/remove_method.rb
index 2714a46b28..b8c01aca0e 100644
--- a/activesupport/lib/active_support/core_ext/module/remove_method.rb
+++ b/activesupport/lib/active_support/core_ext/module/remove_method.rb
@@ -3,4 +3,9 @@ class Module
remove_method(method)
rescue NameError
end
+
+ def redefine_method(method, &block)
+ remove_possible_method(method)
+ define_method(method, &block)
+ end
end \ No newline at end of file
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..f2e7c2351e 100644
--- a/activesupport/lib/active_support/core_ext/object/to_param.rb
+++ b/activesupport/lib/active_support/core_ext/object/to_param.rb
@@ -44,6 +44,6 @@ class Hash
def to_param(namespace = nil)
collect do |key, value|
value.to_query(namespace ? "#{namespace}[#{key}]" : key)
- end.sort * '&'
+ end * '&'
end
end
diff --git a/activesupport/lib/active_support/log_subscriber.rb b/activesupport/lib/active_support/log_subscriber.rb
index 891d718af3..7611aff964 100644
--- a/activesupport/lib/active_support/log_subscriber.rb
+++ b/activesupport/lib/active_support/log_subscriber.rb
@@ -63,15 +63,9 @@ module ActiveSupport
@@flushable_loggers = nil
log_subscriber.public_methods(false).each do |event|
- notifier.subscribe("#{event}.#{namespace}") do |*args|
- next if log_subscriber.logger.nil?
-
- begin
- log_subscriber.send(event, ActiveSupport::Notifications::Event.new(*args))
- rescue Exception => e
- log_subscriber.logger.error "Could not log #{args[0].inspect} event. #{e.class}: #{e.message}"
- end
- end
+ next if 'call' == event.to_s
+
+ notifier.subscribe("#{event}.#{namespace}", log_subscriber)
end
end
@@ -92,6 +86,17 @@ module ActiveSupport
flushable_loggers.each(&:flush)
end
+ def call(message, *args)
+ return unless logger
+
+ method = message.split('.').first
+ begin
+ send(method, ActiveSupport::Notifications::Event.new(message, *args))
+ rescue Exception => e
+ logger.error "Could not log #{message.inspect} event. #{e.class}: #{e.message}"
+ end
+ end
+
protected
%w(info debug warn error fatal unknown).each do |level|
diff --git a/activesupport/lib/active_support/log_subscriber/test_helper.rb b/activesupport/lib/active_support/log_subscriber/test_helper.rb
index 96506a4b2b..9e52cb97a9 100644
--- a/activesupport/lib/active_support/log_subscriber/test_helper.rb
+++ b/activesupport/lib/active_support/log_subscriber/test_helper.rb
@@ -1,4 +1,5 @@
require 'active_support/log_subscriber'
+require 'active_support/buffered_logger'
module ActiveSupport
class LogSubscriber
@@ -33,7 +34,7 @@ module ActiveSupport
module TestHelper
def setup
@logger = MockLogger.new
- @notifier = ActiveSupport::Notifications::Notifier.new(queue)
+ @notifier = ActiveSupport::Notifications::Fanout.new
ActiveSupport::LogSubscriber.colorize_logging = false
@@ -47,10 +48,14 @@ module ActiveSupport
end
class MockLogger
+ include ActiveSupport::BufferedLogger::Severity
+
attr_reader :flush_count
+ attr_accessor :level
- def initialize
+ def initialize(level = DEBUG)
@flush_count = 0
+ @level = level
@logged = Hash.new { |h,k| h[k] = [] }
end
@@ -65,6 +70,14 @@ module ActiveSupport
def flush
@flush_count += 1
end
+
+ ActiveSupport::BufferedLogger::Severity.constants.each do |severity|
+ class_eval <<-EOT, __FILE__, __LINE__ + 1
+ def #{severity.downcase}?
+ #{severity} >= @level
+ end
+ EOT
+ end
end
# Wait notifications to be published.
@@ -81,10 +94,6 @@ module ActiveSupport
def set_logger(logger)
ActiveSupport::LogSubscriber.logger = logger
end
-
- def queue
- ActiveSupport::Notifications::Fanout.new
- end
end
end
-end \ No newline at end of file
+end
diff --git a/activesupport/lib/active_support/notifications.rb b/activesupport/lib/active_support/notifications.rb
index 1444fc1609..93d1907edc 100644
--- a/activesupport/lib/active_support/notifications.rb
+++ b/activesupport/lib/active_support/notifications.rb
@@ -47,34 +47,12 @@ module ActiveSupport
delegate :instrument, :to => :instrumenter
def notifier
- @notifier ||= Notifier.new
+ @notifier ||= Fanout.new
end
def instrumenter
Thread.current[:"instrumentation_#{notifier.object_id}"] ||= Instrumenter.new(notifier)
end
end
-
- class Notifier
- def initialize(queue = Fanout.new)
- @queue = queue
- end
-
- def publish(*args)
- @queue.publish(*args)
- end
-
- def subscribe(pattern = nil, &block)
- @queue.bind(pattern).subscribe(&block)
- end
-
- def unsubscribe(subscriber)
- @queue.unsubscribe(subscriber)
- end
-
- def wait
- @queue.wait
- end
- end
end
end
diff --git a/activesupport/lib/active_support/notifications/fanout.rb b/activesupport/lib/active_support/notifications/fanout.rb
index 300ec842a9..64f315cb6a 100644
--- a/activesupport/lib/active_support/notifications/fanout.rb
+++ b/activesupport/lib/active_support/notifications/fanout.rb
@@ -8,14 +8,11 @@ module ActiveSupport
@listeners_for = {}
end
- def bind(pattern)
- Binding.new(self, pattern)
- end
-
- def subscribe(pattern = nil, &block)
+ def subscribe(pattern = nil, block = Proc.new)
@listeners_for.clear
- @subscribers << Subscriber.new(pattern, &block)
- @subscribers.last
+ Subscriber.new(pattern, block).tap do |s|
+ @subscribers << s
+ end
end
def unsubscribe(subscriber)
@@ -24,69 +21,35 @@ module ActiveSupport
end
def publish(name, *args)
- if listeners = @listeners_for[name]
- listeners.each { |s| s.publish(name, *args) }
- else
- @listeners_for[name] = @subscribers.select { |s| s.publish(name, *args) }
- end
+ listeners_for(name).each { |s| s.publish(name, *args) }
end
- # This is a sync queue, so there is not waiting.
- def wait
+ def listeners_for(name)
+ @listeners_for[name] ||= @subscribers.select { |s| s.subscribed_to?(name) }
end
- # Used for internal implementation only.
- class Binding #:nodoc:
- def initialize(queue, pattern)
- @queue = queue
- @pattern =
- case pattern
- when Regexp, NilClass
- pattern
- else
- /^#{Regexp.escape(pattern.to_s)}$/
- end
- end
-
- def subscribe(&block)
- @queue.subscribe(@pattern, &block)
- end
+ # This is a sync queue, so there is not waiting.
+ def wait
end
class Subscriber #:nodoc:
- def initialize(pattern, &block)
+ def initialize(pattern, delegate)
@pattern = pattern
- @block = block
+ @delegate = delegate
end
- def publish(*args)
- return unless subscribed_to?(args.first)
- push(*args)
- true
- end
-
- def drained?
- true
+ def publish(message, *args)
+ @delegate.call(message, *args)
end
def subscribed_to?(name)
- !@pattern || @pattern =~ name.to_s
+ !@pattern || @pattern === name.to_s
end
def matches?(subscriber_or_name)
- case subscriber_or_name
- when String
- @pattern && @pattern =~ subscriber_or_name
- when self
- true
- end
+ self === subscriber_or_name ||
+ @pattern && @pattern === subscriber_or_name
end
-
- private
-
- def push(*args)
- @block.call(*args)
- end
end
end
end
diff --git a/activesupport/lib/active_support/notifications/instrumenter.rb b/activesupport/lib/active_support/notifications/instrumenter.rb
index 7e89402822..e98189f899 100644
--- a/activesupport/lib/active_support/notifications/instrumenter.rb
+++ b/activesupport/lib/active_support/notifications/instrumenter.rb
@@ -9,23 +9,30 @@ module ActiveSupport
def initialize(notifier)
@id = unique_id
@notifier = notifier
+ @started = nil
+ @finished = nil
end
# Instrument the given block by measuring the time taken to execute it
# and publish it. Notice that events get sent even if an error occurs
# in the passed-in block
def instrument(name, payload={})
- time = Time.now
begin
+ @started = Time.now
yield(payload) if block_given?
rescue Exception => e
payload[:exception] = [e.class.name, e.message]
raise e
ensure
- @notifier.publish(name, time, Time.now, @id, payload)
+ @finished = Time.now
+ @notifier.publish(name, @started, @finished, @id, payload)
end
end
+ def elapsed
+ 1000.0 * (@finished.to_f - @started.to_f)
+ end
+
private
def unique_id
SecureRandom.hex(10)
@@ -33,7 +40,7 @@ module ActiveSupport
end
class Event
- attr_reader :name, :time, :end, :transaction_id, :payload
+ attr_reader :name, :time, :end, :transaction_id, :payload, :duration
def initialize(name, start, ending, transaction_id, payload)
@name = name
@@ -41,14 +48,11 @@ module ActiveSupport
@time = start
@transaction_id = transaction_id
@end = ending
- end
-
- def duration
- @duration ||= 1000.0 * (@end - @time)
+ @duration = 1000.0 * (@end - @time)
end
def parent_of?(event)
- start = (self.time - event.time) * 1000
+ start = (time - event.time) * 1000
start <= 0 && (start + duration >= event.duration)
end
end
diff --git a/activesupport/test/buffered_logger_test.rb b/activesupport/test/buffered_logger_test.rb
index 850febb959..97c0ef14db 100644
--- a/activesupport/test/buffered_logger_test.rb
+++ b/activesupport/test/buffered_logger_test.rb
@@ -1,9 +1,12 @@
require 'abstract_unit'
+require 'multibyte_test_helpers'
require 'stringio'
require 'fileutils'
require 'active_support/buffered_logger'
class BufferedLoggerTest < Test::Unit::TestCase
+ include MultibyteTestHelpers
+
Logger = ActiveSupport::BufferedLogger
def setup
@@ -146,4 +149,16 @@ class BufferedLoggerTest < Test::Unit::TestCase
@logger.expects :clear_buffer
@logger.flush
end
+
+ def test_buffer_multibyte
+ @logger.auto_flushing = 2
+ @logger.info(UNICODE_STRING)
+ @logger.info(BYTE_STRING)
+ assert @output.string.include?(UNICODE_STRING)
+ byte_string = @output.string.dup
+ if byte_string.respond_to?(:force_encoding)
+ byte_string.force_encoding("ASCII-8BIT")
+ end
+ assert byte_string.include?(BYTE_STRING)
+ end
end
diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb
index 7b2c10908f..5d9846a216 100644
--- a/activesupport/test/core_ext/hash_ext_test.rb
+++ b/activesupport/test/core_ext/hash_ext_test.rb
@@ -2,6 +2,8 @@ require 'abstract_unit'
require 'active_support/core_ext/hash'
require 'bigdecimal'
require 'active_support/core_ext/string/access'
+require 'active_support/ordered_hash'
+require 'active_support/core_ext/object/conversions'
class HashExtTest < Test::Unit::TestCase
def setup
@@ -449,6 +451,33 @@ class IWriteMyOwnXML
end
end
+class HashExtToParamTests < Test::Unit::TestCase
+ class ToParam < String
+ def to_param
+ "#{self}-1"
+ end
+ end
+
+ def test_string_hash
+ assert_equal '', {}.to_param
+ assert_equal 'hello=world', { :hello => "world" }.to_param
+ assert_equal 'hello=10', { "hello" => 10 }.to_param
+ assert_equal 'hello=world&say_bye=true', ActiveSupport::OrderedHash[:hello, "world", "say_bye", true].to_param
+ end
+
+ def test_number_hash
+ assert_equal '10=20&30=40&50=60', ActiveSupport::OrderedHash[10, 20, 30, 40, 50, 60].to_param
+ end
+
+ def test_to_param_hash
+ assert_equal 'custom=param-1&custom2=param2-1', ActiveSupport::OrderedHash[ToParam.new('custom'), ToParam.new('param'), ToParam.new('custom2'), ToParam.new('param2')].to_param
+ end
+
+ def test_to_param_hash_escapes_its_keys_and_values
+ assert_equal 'param+1=A+string+with+%2F+characters+%26+that+should+be+%3F+escaped', { 'param 1' => 'A string with / characters & that should be ? escaped' }.to_param
+ end
+end
+
class HashToXmlTest < Test::Unit::TestCase
def setup
@xml_options = { :root => :person, :skip_instruct => true, :indent => 0 }
diff --git a/activesupport/test/multibyte_test_helpers.rb b/activesupport/test/multibyte_test_helpers.rb
index 597f949059..8839b75601 100644
--- a/activesupport/test/multibyte_test_helpers.rb
+++ b/activesupport/test/multibyte_test_helpers.rb
@@ -4,6 +4,9 @@ module MultibyteTestHelpers
UNICODE_STRING = 'こにちわ'
ASCII_STRING = 'ohayo'
BYTE_STRING = "\270\236\010\210\245"
+ if BYTE_STRING.respond_to?(:force_encoding)
+ BYTE_STRING.force_encoding("ASCII-8BIT")
+ end
def chars(str)
ActiveSupport::Multibyte::Chars.new(str)
@@ -16,4 +19,4 @@ module MultibyteTestHelpers
def assert_equal_codepoints(expected, actual, message=nil)
assert_equal(inspect_codepoints(expected), inspect_codepoints(actual), message)
end
-end \ No newline at end of file
+end
diff --git a/activesupport/test/notifications_test.rb b/activesupport/test/notifications_test.rb
index 3e16e01d89..41e8ca4ae7 100644
--- a/activesupport/test/notifications_test.rb
+++ b/activesupport/test/notifications_test.rb
@@ -11,14 +11,11 @@ module Notifications
@named_subscription = @notifier.subscribe("named.subscription") { |*args| @named_events << event(*args) }
end
- private
- def event(*args)
- ActiveSupport::Notifications::Event.new(*args)
- end
+ private
- def drain
- @notifier.wait
- end
+ def event(*args)
+ ActiveSupport::Notifications::Event.new(*args)
+ end
end
class UnsubscribeTest < TestCase
@@ -132,13 +129,10 @@ module Notifications
def test_instrument_returns_block_result
assert_equal 2, instrument(:awesome) { 1 + 1 }
- drain
end
def test_instrument_yields_the_paylod_for_further_modification
assert_equal 2, instrument(:awesome) { |p| p[:result] = 1 + 1 }
- drain
-
assert_equal 1, @events.size
assert_equal :awesome, @events.first.name
assert_equal Hash[:result => 2], @events.first.payload
@@ -154,15 +148,11 @@ module Notifications
1 + 1
end
- drain
-
assert_equal 1, @events.size
assert_equal :wot, @events.first.name
assert_equal Hash[:payload => "child"], @events.first.payload
end
- drain
-
assert_equal 2, @events.size
assert_equal :awesome, @events.last.name
assert_equal Hash[:payload => "notifications"], @events.last.payload
@@ -177,16 +167,22 @@ module Notifications
assert_equal "FAIL", e.message
end
- drain
assert_equal 1, @events.size
assert_equal Hash[:payload => "notifications",
:exception => ["RuntimeError", "FAIL"]], @events.last.payload
end
+ def test_elapsed
+ instrument(:something) do
+ sleep(0.001)
+ end
+
+ # Elapsed returns duration in ms
+ assert_in_delta 1, ActiveSupport::Notifications.instrumenter.elapsed, 100
+ end
+
def test_event_is_pushed_even_without_block
instrument(:awesome, :payload => "notifications")
- drain
-
assert_equal 1, @events.size
assert_equal :awesome, @events.last.name
assert_equal Hash[:payload => "notifications"], @events.last.payload
@@ -200,7 +196,7 @@ module Notifications
assert_equal :foo, event.name
assert_equal time, event.time
- assert_in_delta 10.0, event.duration, 0.00000000000001
+ assert_in_delta 10.0, event.duration, 0.00001
end
def test_events_consumes_information_given_as_payload