aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/CHANGELOG.md37
-rw-r--r--activesupport/Rakefile4
-rw-r--r--activesupport/lib/active_support/backtrace_cleaner.rb16
-rw-r--r--activesupport/lib/active_support/cache.rb2
-rw-r--r--activesupport/lib/active_support/callbacks.rb16
-rw-r--r--activesupport/lib/active_support/core_ext/class/attribute.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/date_time/conversions.rb10
-rw-r--r--activesupport/lib/active_support/core_ext/module/delegation.rb4
-rw-r--r--activesupport/lib/active_support/core_ext/time/calculations.rb12
-rw-r--r--activesupport/lib/active_support/dependencies.rb6
-rw-r--r--activesupport/lib/active_support/file_update_checker.rb2
-rw-r--r--activesupport/lib/active_support/hash_with_indifferent_access.rb24
-rw-r--r--activesupport/lib/active_support/inflector/methods.rb15
-rw-r--r--activesupport/lib/active_support/notifications.rb4
-rw-r--r--activesupport/lib/active_support/testing/declarative.rb9
-rw-r--r--activesupport/lib/active_support/testing/setup_and_teardown.rb19
-rw-r--r--activesupport/lib/active_support/time_with_zone.rb6
-rw-r--r--activesupport/test/clean_backtrace_test.rb21
-rw-r--r--activesupport/test/constantize_test_cases.rb8
-rw-r--r--activesupport/test/core_ext/date_time_ext_test.rb10
-rw-r--r--activesupport/test/core_ext/hash_ext_test.rb37
-rw-r--r--activesupport/test/core_ext/time_ext_test.rb22
-rw-r--r--activesupport/test/core_ext/time_with_zone_test.rb10
-rw-r--r--activesupport/test/dependencies/raises_exception_without_blame_file.rb5
-rw-r--r--activesupport/test/dependencies_test.rb8
-rw-r--r--activesupport/test/load_paths_test.rb4
-rw-r--r--activesupport/test/xml_mini/jdom_engine_test.rb2
-rw-r--r--activesupport/test/xml_mini/libxml_engine_test.rb3
-rw-r--r--activesupport/test/xml_mini/libxmlsax_engine_test.rb3
-rw-r--r--activesupport/test/xml_mini/nokogiri_engine_test.rb3
-rw-r--r--activesupport/test/xml_mini/nokogirisax_engine_test.rb3
-rw-r--r--activesupport/test/xml_mini/rexml_engine_test.rb3
32 files changed, 272 insertions, 57 deletions
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 1982811500..45f71daa08 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,3 +1,40 @@
+* Fix return value from `BacktraceCleaner#noise` when the cleaner is configured
+ with multiple silencers.
+
+ Fixes #11030
+
+ *Mark J. Titorenko*
+
+* `HashWithIndifferentAccess#select` now returns a `HashWithIndifferentAccess`
+ instance instead of a `Hash` instance.
+
+ Fixes #10723
+
+ *Albert Llop*
+
+* Add `DateTime#usec` and `DateTime#nsec` so that `ActiveSupport::TimeWithZone` keeps
+ sub-second resolution when wrapping a `DateTime` value.
+
+ Fixes #10855
+
+ *Andrew White*
+
+* Fix `ActiveSupport::Dependencies::Loadable#load_dependency` calling
+ `#blame_file!` on Exceptions that do not have the Blamable mixin
+
+ *Andrew Kreiling*
+
+* Override `Time.at` to support the passing of Time-like values when called with a single argument.
+
+ *Andrew White*
+
+* Prevent side effects to hashes inside arrays when
+ `Hash#with_indifferent_access` is called.
+
+ Fixes #10526
+
+ *Yves Senn*
+
* Raise an error when multiple `included` blocks are defined for a Concern.
The old behavior would silently discard previously defined blocks, running
only the last one.
diff --git a/activesupport/Rakefile b/activesupport/Rakefile
index f50225a9f0..99770bace9 100644
--- a/activesupport/Rakefile
+++ b/activesupport/Rakefile
@@ -14,7 +14,7 @@ namespace :test do
task :isolated do
ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME'))
Dir.glob("test/**/*_test.rb").all? do |file|
- sh(ruby, '-Ilib:test', file)
+ sh(ruby, '-w', '-Ilib:test', file)
end or raise "Failures"
end
end
@@ -25,7 +25,7 @@ Gem::PackageTask.new(spec) do |p|
p.gem_spec = spec
end
-desc "Release to gemcutter"
+desc "Release to rubygems"
task :release => :package do
require 'rake/gemcutter'
Rake::Gemcutter::Tasks.new(spec).define
diff --git a/activesupport/lib/active_support/backtrace_cleaner.rb b/activesupport/lib/active_support/backtrace_cleaner.rb
index 4b41e6247d..c88ae3e661 100644
--- a/activesupport/lib/active_support/backtrace_cleaner.rb
+++ b/activesupport/lib/active_support/backtrace_cleaner.rb
@@ -13,17 +13,17 @@ module ActiveSupport
# can focus on the rest.
#
# bc = BacktraceCleaner.new
- # bc.add_filter { |line| line.gsub(Rails.root, '') }
- # bc.add_silencer { |line| line =~ /mongrel|rubygems/ }
- # bc.clean(exception.backtrace) # will strip the Rails.root prefix and skip any lines from mongrel or rubygems
+ # bc.add_filter { |line| line.gsub(Rails.root, '') } # strip the Rails.root prefix
+ # bc.add_silencer { |line| line =~ /mongrel|rubygems/ } # skip any lines from mongrel or rubygems
+ # bc.clean(exception.backtrace) # perform the cleanup
#
# To reconfigure an existing BacktraceCleaner (like the default one in Rails)
# and show as much data as possible, you can always call
# <tt>BacktraceCleaner#remove_silencers!</tt>, which will restore the
# backtrace to a pristine state. If you need to reconfigure an existing
# BacktraceCleaner so that it does not filter or modify the paths of any lines
- # of the backtrace, you can call BacktraceCleaner#remove_filters! These two
- # methods will give you a completely untouched backtrace.
+ # of the backtrace, you can call <tt>BacktraceCleaner#remove_filters!<tt>
+ # These two methods will give you a completely untouched backtrace.
#
# Inspired by the Quiet Backtrace gem by Thoughtbot.
class BacktraceCleaner
@@ -97,11 +97,7 @@ module ActiveSupport
end
def noise(backtrace)
- @silencers.each do |s|
- backtrace = backtrace.select { |line| s.call(line) }
- end
-
- backtrace
+ backtrace - silence(backtrace)
end
end
end
diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb
index b1ab5570a8..c539048a85 100644
--- a/activesupport/lib/active_support/cache.rb
+++ b/activesupport/lib/active_support/cache.rb
@@ -228,7 +228,7 @@ module ActiveSupport
#
# Setting <tt>:race_condition_ttl</tt> is very useful in situations where
# a cache entry is used very frequently and is under heavy load. If a
- # cache expires and due to heavy load seven different processes will try
+ # cache expires and due to heavy load several different processes will try
# to read data natively and then they all will try to write to cache. To
# avoid that case the first process to find an expired cache entry will
# bump the cache expiration time by the value set in <tt>:race_condition_ttl</tt>.
diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb
index 85b7669353..2cffa342ef 100644
--- a/activesupport/lib/active_support/callbacks.rb
+++ b/activesupport/lib/active_support/callbacks.rb
@@ -94,6 +94,15 @@ module ActiveSupport
def halted_callback_hook(filter)
end
+ module Conditionals # :nodoc:
+ class Value
+ def initialize(&block)
+ @block = block
+ end
+ def call(target, value); @block.call(value); end
+ end
+ end
+
module Filters
Environment = Struct.new(:target, :halted, :value, :run_block)
@@ -403,8 +412,8 @@ module ActiveSupport
# the same after this point:
#
# Symbols:: Already methods.
- # Strings:: class_eval'ed into methods.
- # Procs:: define_method'ed into methods.
+ # Strings:: class_eval'd into methods.
+ # Procs:: using define_method compiled into methods.
# Objects::
# a method is created that calls the before_foo method
# on the object.
@@ -415,6 +424,7 @@ module ActiveSupport
when String
l = eval "lambda { |value| #{filter} }"
lambda { |target, value| target.instance_exec(value, &l) }
+ when Conditionals::Value then filter
when ::Proc
if filter.arity > 1
return lambda { |target, _, &block|
@@ -648,7 +658,7 @@ module ActiveSupport
#
# * <tt>:terminator</tt> - Determines when a before filter will halt the
# callback chain, preventing following callbacks from being called and
- # the event from being triggered. This is a string to be eval'ed. The
+ # the event from being triggered. This is a string to be eval'd. The
# result of the callback is available in the +result+ variable.
#
# define_callbacks :validate, terminator: 'result == false'
diff --git a/activesupport/lib/active_support/core_ext/class/attribute.rb b/activesupport/lib/active_support/core_ext/class/attribute.rb
index 6fa9967a28..83038f9da5 100644
--- a/activesupport/lib/active_support/core_ext/class/attribute.rb
+++ b/activesupport/lib/active_support/core_ext/class/attribute.rb
@@ -70,7 +70,6 @@ class Class
# To opt out of both instance methods, pass <tt>instance_accessor: false</tt>.
def class_attribute(*attrs)
options = attrs.extract_options!
- # double assignment is used to avoid "assigned but unused variable" warning
instance_reader = options.fetch(:instance_accessor, true) && options.fetch(:instance_reader, true)
instance_writer = options.fetch(:instance_accessor, true) && options.fetch(:instance_writer, true)
instance_predicate = options.fetch(:instance_predicate, true)
diff --git a/activesupport/lib/active_support/core_ext/date_time/conversions.rb b/activesupport/lib/active_support/core_ext/date_time/conversions.rb
index df07917d19..c44626aed9 100644
--- a/activesupport/lib/active_support/core_ext/date_time/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/date_time/conversions.rb
@@ -80,6 +80,16 @@ class DateTime
seconds_since_unix_epoch.to_i
end
+ # Returns the fraction of a second as microseconds
+ def usec
+ (sec_fraction * 1_000_000).to_i
+ end
+
+ # Returns the fraction of a second as nanoseconds
+ def nsec
+ (sec_fraction * 1_000_000_000).to_i
+ end
+
private
def offset_in_seconds
diff --git a/activesupport/lib/active_support/core_ext/module/delegation.rb b/activesupport/lib/active_support/core_ext/module/delegation.rb
index eabc1bf84a..9d4b78e242 100644
--- a/activesupport/lib/active_support/core_ext/module/delegation.rb
+++ b/activesupport/lib/active_support/core_ext/module/delegation.rb
@@ -164,7 +164,7 @@ class Module
#
# Reason is twofold: On one hand doing less calls is in general better.
# On the other hand it could be that the target has side-effects,
- # whereas conceptualy, from the user point of view, the delegator should
+ # whereas conceptually, from the user point of view, the delegator should
# be doing one call.
if allow_nil
module_eval(<<-EOS, file, line - 3)
@@ -195,4 +195,4 @@ class Module
end
end
-class DelegationError < StandardError ; end \ No newline at end of file
+class DelegationError < StandardError ; end
diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb
index a3ce7dbe3f..c65f20c2d5 100644
--- a/activesupport/lib/active_support/core_ext/time/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/time/calculations.rb
@@ -65,6 +65,18 @@ class Time
def current
::Time.zone ? ::Time.zone.now : ::Time.now
end
+
+ # Layers additional behavior on Time.at so that ActiveSupport::TimeWithZone and DateTime
+ # instances can be used when called with a single argument
+ def at_with_coercion(*args)
+ if args.size == 1 && args.first.acts_like?(:time)
+ at_without_coercion(args.first.to_i)
+ else
+ at_without_coercion(*args)
+ end
+ end
+ alias_method :at_without_coercion, :at
+ alias_method :at, :at_with_coercion
end
# Seconds since midnight: Time.now.seconds_since_midnight
diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb
index fff4c776a9..73559bfe0e 100644
--- a/activesupport/lib/active_support/dependencies.rb
+++ b/activesupport/lib/active_support/dependencies.rb
@@ -213,7 +213,7 @@ module ActiveSupport #:nodoc:
yield
end
rescue Exception => exception # errors from loading file
- exception.blame_file! file
+ exception.blame_file! file if exception.respond_to? :blame_file!
raise
end
@@ -416,7 +416,7 @@ module ActiveSupport #:nodoc:
def load_file(path, const_paths = loadable_constants_for_path(path))
log_call path, const_paths
const_paths = [const_paths].compact unless const_paths.is_a? Array
- parent_paths = const_paths.collect { |const_path| const_path[/.*(?=::)/] || :Object }
+ parent_paths = const_paths.collect { |const_path| const_path[/.*(?=::)/] || ::Object }
result = nil
newly_defined_paths = new_constants_in(*parent_paths) do
@@ -634,7 +634,7 @@ module ActiveSupport #:nodoc:
when String then desc.sub(/^::/, '')
when Symbol then desc.to_s
when Module
- desc.name.presence ||
+ desc.name ||
raise(ArgumentError, "Anonymous modules have no name to be referenced by")
else raise TypeError, "Not a valid constant descriptor: #{desc.inspect}"
end
diff --git a/activesupport/lib/active_support/file_update_checker.rb b/activesupport/lib/active_support/file_update_checker.rb
index 20136dd1b0..d6918bede2 100644
--- a/activesupport/lib/active_support/file_update_checker.rb
+++ b/activesupport/lib/active_support/file_update_checker.rb
@@ -115,7 +115,7 @@ module ActiveSupport
end
def compile_glob(hash)
- hash.freeze # Freeze so changes aren't accidently pushed
+ hash.freeze # Freeze so changes aren't accidentally pushed
return if hash.empty?
globs = hash.map do |key, value|
diff --git a/activesupport/lib/active_support/hash_with_indifferent_access.rb b/activesupport/lib/active_support/hash_with_indifferent_access.rb
index bdb8877f55..95e03ba95c 100644
--- a/activesupport/lib/active_support/hash_with_indifferent_access.rb
+++ b/activesupport/lib/active_support/hash_with_indifferent_access.rb
@@ -91,7 +91,7 @@ module ActiveSupport
#
# This value can be later fetched using either +:key+ or +'key'+.
def []=(key, value)
- regular_writer(convert_key(key), convert_value(value))
+ regular_writer(convert_key(key), convert_value(value, for: :assignment))
end
alias_method :store, :[]=
@@ -224,14 +224,18 @@ module ActiveSupport
undef :symbolize_keys!
undef :deep_symbolize_keys!
def symbolize_keys; to_hash.symbolize_keys! end
- def deep_symbolize_keys; to_hash.deep_symbolize_keys end
+ def deep_symbolize_keys; to_hash.deep_symbolize_keys! end
def to_options!; self end
+ def select(*args, &block)
+ dup.select!(*args, &block)
+ end
+
# Convert to a regular hash with string keys.
def to_hash
_new_hash= {}
each do |key, value|
- _new_hash[convert_key(key)] = convert_value(value, true)
+ _new_hash[convert_key(key)] = convert_value(value, for: :to_hash)
end
Hash.new(default).merge!(_new_hash)
end
@@ -241,12 +245,18 @@ module ActiveSupport
key.kind_of?(Symbol) ? key.to_s : key
end
- def convert_value(value, _convert_for_to_hash = false)
+ def convert_value(value, options = {})
if value.is_a? Hash
- _convert_for_to_hash ? value.to_hash : value.nested_under_indifferent_access
+ if options[:for] == :to_hash
+ value.to_hash
+ else
+ value.nested_under_indifferent_access
+ end
elsif value.is_a?(Array)
- value = value.dup if value.frozen?
- value.map! { |e| convert_value(e, _convert_for_to_hash) }
+ unless options[:for] == :assignment
+ value = value.dup
+ end
+ value.map! { |e| convert_value(e, options) }
else
value
end
diff --git a/activesupport/lib/active_support/inflector/methods.rb b/activesupport/lib/active_support/inflector/methods.rb
index 39648727fd..9ca5a388f8 100644
--- a/activesupport/lib/active_support/inflector/methods.rb
+++ b/activesupport/lib/active_support/inflector/methods.rb
@@ -1,6 +1,5 @@
# encoding: utf-8
-require 'active_support/inflector/inflections'
require 'active_support/inflections'
module ActiveSupport
@@ -219,7 +218,12 @@ module ActiveSupport
# unknown.
def constantize(camel_cased_word)
names = camel_cased_word.split('::')
- names.shift if names.empty? || names.first.empty?
+
+ # Trigger a builtin NameError exception including the ill-formed constant in the message.
+ Object.const_get(camel_cased_word) if names.empty?
+
+ # Remove the first blank element in case of '::ClassName' notation.
+ names.shift if names.size > 1 && names.first.empty?
names.inject(Object) do |constant, name|
if constant == Object
@@ -314,9 +318,14 @@ module ActiveSupport
private
# Mount a regular expression that will match part by part of the constant.
- # For instance, Foo::Bar::Baz will generate Foo(::Bar(::Baz)?)?
+ #
+ # const_regexp("Foo::Bar::Baz") # => /Foo(::Bar(::Baz)?)?/
+ # const_regexp("::") # => /::/
def const_regexp(camel_cased_word) #:nodoc:
parts = camel_cased_word.split("::")
+
+ return Regexp.escape(camel_cased_word) if parts.blank?
+
last = parts.pop
parts.reverse.inject(last) do |acc, part|
diff --git a/activesupport/lib/active_support/notifications.rb b/activesupport/lib/active_support/notifications.rb
index c45358bba9..b32aa75e59 100644
--- a/activesupport/lib/active_support/notifications.rb
+++ b/activesupport/lib/active_support/notifications.rb
@@ -143,8 +143,8 @@ module ActiveSupport
#
# == Default Queue
#
- # Notifications ships with a queue implementation that consumes and publish events
- # to log subscribers in a thread. You can use any queue implementation you want.
+ # Notifications ships with a queue implementation that consumes and publishes events
+ # to all log subscribers. You can use any queue implementation you want.
#
module Notifications
class << self
diff --git a/activesupport/lib/active_support/testing/declarative.rb b/activesupport/lib/active_support/testing/declarative.rb
index 508e37254a..1fa73caefa 100644
--- a/activesupport/lib/active_support/testing/declarative.rb
+++ b/activesupport/lib/active_support/testing/declarative.rb
@@ -19,9 +19,12 @@ module ActiveSupport
end
unless defined?(Spec)
- # test "verify something" do
- # ...
- # end
+ # Helper to define a test method using a String. Under the hood, it replaces
+ # spaces with underscores and defines the test method.
+ #
+ # test "verify something" do
+ # ...
+ # end
def test(name, &block)
test_name = "test_#{name.gsub(/\s+/,'_')}".to_sym
defined = instance_method(test_name) rescue false
diff --git a/activesupport/lib/active_support/testing/setup_and_teardown.rb b/activesupport/lib/active_support/testing/setup_and_teardown.rb
index a65148cf1f..33f2b8dc9b 100644
--- a/activesupport/lib/active_support/testing/setup_and_teardown.rb
+++ b/activesupport/lib/active_support/testing/setup_and_teardown.rb
@@ -3,6 +3,19 @@ require 'active_support/callbacks'
module ActiveSupport
module Testing
+ # Adds support for +setup+ and +teardown+ callbacks.
+ # These callbacks serve as a replacement to overwriting the
+ # <tt>#setup</tt> and <tt>#teardown</tt> methods of your TestCase.
+ #
+ # class ExampleTest < ActiveSupport::TestCase
+ # setup do
+ # # ...
+ # end
+ #
+ # teardown do
+ # # ...
+ # end
+ # end
module SetupAndTeardown
extend ActiveSupport::Concern
@@ -12,21 +25,23 @@ module ActiveSupport
end
module ClassMethods
+ # Add a callback, which runs before <tt>TestCase#setup</tt>.
def setup(*args, &block)
set_callback(:setup, :before, *args, &block)
end
+ # Add a callback, which runs after <tt>TestCase#teardown</tt>.
def teardown(*args, &block)
set_callback(:teardown, :after, *args, &block)
end
end
- def before_setup
+ def before_setup # :nodoc:
super
run_callbacks :setup
end
- def after_teardown
+ def after_teardown # :nodoc:
run_callbacks :teardown
super
end
diff --git a/activesupport/lib/active_support/time_with_zone.rb b/activesupport/lib/active_support/time_with_zone.rb
index 4a032b0ad0..95b9b8e5ae 100644
--- a/activesupport/lib/active_support/time_with_zone.rb
+++ b/activesupport/lib/active_support/time_with_zone.rb
@@ -292,7 +292,7 @@ module ActiveSupport
end
end
- %w(year mon month day mday wday yday hour min sec to_date).each do |method_name|
+ %w(year mon month day mday wday yday hour min sec usec nsec to_date).each do |method_name|
class_eval <<-EOV, __FILE__, __LINE__ + 1
def #{method_name} # def month
time.#{method_name} # time.month
@@ -300,10 +300,6 @@ module ActiveSupport
EOV
end
- def usec
- time.respond_to?(:usec) ? time.usec : 0
- end
-
def to_a
[time.sec, time.min, time.hour, time.day, time.mon, time.year, time.wday, time.yday, dst?, zone]
end
diff --git a/activesupport/test/clean_backtrace_test.rb b/activesupport/test/clean_backtrace_test.rb
index b14950acb3..dd67a45cf6 100644
--- a/activesupport/test/clean_backtrace_test.rb
+++ b/activesupport/test/clean_backtrace_test.rb
@@ -36,6 +36,27 @@ class BacktraceCleanerSilencerTest < ActiveSupport::TestCase
end
end
+class BacktraceCleanerMultipleSilencersTest < ActiveSupport::TestCase
+ def setup
+ @bc = ActiveSupport::BacktraceCleaner.new
+ @bc.add_silencer { |line| line =~ /mongrel/ }
+ @bc.add_silencer { |line| line =~ /yolo/ }
+ end
+
+ test "backtrace should not contain lines that match the silencers" do
+ assert_equal \
+ [ "/other/class.rb" ],
+ @bc.clean([ "/mongrel/class.rb", "/other/class.rb", "/mongrel/stuff.rb", "/other/yolo.rb" ])
+ end
+
+ test "backtrace should only contain lines that match the silencers" do
+ assert_equal \
+ [ "/mongrel/class.rb", "/mongrel/stuff.rb", "/other/yolo.rb" ],
+ @bc.clean([ "/mongrel/class.rb", "/other/class.rb", "/mongrel/stuff.rb", "/other/yolo.rb" ],
+ :noise)
+ end
+end
+
class BacktraceCleanerFilterAndSilencerTest < ActiveSupport::TestCase
def setup
@bc = ActiveSupport::BacktraceCleaner.new
diff --git a/activesupport/test/constantize_test_cases.rb b/activesupport/test/constantize_test_cases.rb
index 9b62295c96..bbeb710a0c 100644
--- a/activesupport/test/constantize_test_cases.rb
+++ b/activesupport/test/constantize_test_cases.rb
@@ -34,8 +34,6 @@ module ConstantizeTestCases
assert_equal Case::Dice, yield("Object::Case::Dice")
assert_equal ConstantizeTestCases, yield("ConstantizeTestCases")
assert_equal ConstantizeTestCases, yield("::ConstantizeTestCases")
- assert_equal Object, yield("")
- assert_equal Object, yield("::")
assert_raises(NameError) { yield("UnknownClass") }
assert_raises(NameError) { yield("UnknownClass::Ace") }
assert_raises(NameError) { yield("UnknownClass::Ace::Base") }
@@ -45,6 +43,8 @@ module ConstantizeTestCases
assert_raises(NameError) { yield("Ace::Base::ConstantizeTestCases") }
assert_raises(NameError) { yield("Ace::Gas::Base") }
assert_raises(NameError) { yield("Ace::Gas::ConstantizeTestCases") }
+ assert_raises(NameError) { yield("") }
+ assert_raises(NameError) { yield("::") }
end
def run_safe_constantize_tests_on
@@ -58,8 +58,8 @@ module ConstantizeTestCases
assert_equal Case::Dice, yield("Object::Case::Dice")
assert_equal ConstantizeTestCases, yield("ConstantizeTestCases")
assert_equal ConstantizeTestCases, yield("::ConstantizeTestCases")
- assert_equal Object, yield("")
- assert_equal Object, yield("::")
+ assert_nil yield("")
+ assert_nil yield("::")
assert_nil yield("UnknownClass")
assert_nil yield("UnknownClass::Ace")
assert_nil yield("UnknownClass::Ace::Base")
diff --git a/activesupport/test/core_ext/date_time_ext_test.rb b/activesupport/test/core_ext/date_time_ext_test.rb
index 3e76b8a9b1..571344b728 100644
--- a/activesupport/test/core_ext/date_time_ext_test.rb
+++ b/activesupport/test/core_ext/date_time_ext_test.rb
@@ -327,6 +327,16 @@ class DateTimeExtCalculationsTest < ActiveSupport::TestCase
assert_equal 946684800, DateTime.civil(1999,12,31,19,0,0,Rational(-5,24)).to_i
end
+ def test_usec
+ assert_equal 0, DateTime.civil(2000).usec
+ assert_equal 500000, DateTime.civil(2000, 1, 1, 0, 0, Rational(1,2)).usec
+ end
+
+ def test_nsec
+ assert_equal 0, DateTime.civil(2000).nsec
+ assert_equal 500000000, DateTime.civil(2000, 1, 1, 0, 0, Rational(1,2)).nsec
+ end
+
protected
def with_env_tz(new_tz = 'US/Eastern')
old_tz, ENV['TZ'] = ENV['TZ'], new_tz
diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb
index dfcc6cd12a..c6d7ab618c 100644
--- a/activesupport/test/core_ext/hash_ext_test.rb
+++ b/activesupport/test/core_ext/hash_ext_test.rb
@@ -480,6 +480,36 @@ class HashExtTest < ActiveSupport::TestCase
assert_equal hash.delete('a'), nil
end
+ def test_indifferent_select
+ hash = ActiveSupport::HashWithIndifferentAccess.new(@strings).select {|k,v| v == 1}
+
+ assert_equal({ 'a' => 1 }, hash)
+ assert_instance_of ActiveSupport::HashWithIndifferentAccess, hash
+ end
+
+ def test_indifferent_select_bang
+ indifferent_strings = ActiveSupport::HashWithIndifferentAccess.new(@strings)
+ indifferent_strings.select! {|k,v| v == 1}
+
+ assert_equal({ 'a' => 1 }, indifferent_strings)
+ assert_instance_of ActiveSupport::HashWithIndifferentAccess, indifferent_strings
+ end
+
+ def test_indifferent_reject
+ hash = ActiveSupport::HashWithIndifferentAccess.new(@strings).reject {|k,v| v != 1}
+
+ assert_equal({ 'a' => 1 }, hash)
+ assert_instance_of ActiveSupport::HashWithIndifferentAccess, hash
+ end
+
+ def test_indifferent_reject_bang
+ indifferent_strings = ActiveSupport::HashWithIndifferentAccess.new(@strings)
+ indifferent_strings.reject! {|k,v| v != 1}
+
+ assert_equal({ 'a' => 1 }, indifferent_strings)
+ assert_instance_of ActiveSupport::HashWithIndifferentAccess, indifferent_strings
+ end
+
def test_indifferent_to_hash
# Should convert to a Hash with String keys.
assert_equal @strings, @mixed.with_indifferent_access.to_hash
@@ -503,6 +533,13 @@ class HashExtTest < ActiveSupport::TestCase
assert_equal [1], hash[:a]
end
+ def test_with_indifferent_access_has_no_side_effects_on_existing_hash
+ hash = {content: [{:foo => :bar, 'bar' => 'baz'}]}
+ hash.with_indifferent_access
+
+ assert_equal [:foo, "bar"], hash[:content].first.keys
+ end
+
def test_indifferent_hash_with_array_of_hashes
hash = { "urls" => { "url" => [ { "address" => "1" }, { "address" => "2" } ] }}.with_indifferent_access
assert_equal "1", hash[:urls][:url].first[:address]
diff --git a/activesupport/test/core_ext/time_ext_test.rb b/activesupport/test/core_ext/time_ext_test.rb
index 4e53aff00b..eefcdbb1b3 100644
--- a/activesupport/test/core_ext/time_ext_test.rb
+++ b/activesupport/test/core_ext/time_ext_test.rb
@@ -741,6 +741,28 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase
assert_equal(-1, Time.utc(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 1), ActiveSupport::TimeZone['UTC'] ))
end
+ def test_at_with_datetime
+ assert_equal Time.utc(2000, 1, 1, 0, 0, 0), Time.at(DateTime.civil(2000, 1, 1, 0, 0, 0))
+
+ # Only test this if the underlying Time.at raises a TypeError
+ begin
+ Time.at_without_coercion(Time.now, 0)
+ rescue TypeError
+ assert_raise(TypeError) { assert_equal(Time.utc(2000, 1, 1, 0, 0, 0), Time.at(DateTime.civil(2000, 1, 1, 0, 0, 0), 0)) }
+ end
+ end
+
+ def test_at_with_time_with_zone
+ assert_equal Time.utc(2000, 1, 1, 0, 0, 0), Time.at(ActiveSupport::TimeWithZone.new(Time.utc(2000, 1, 1, 0, 0, 0), ActiveSupport::TimeZone['UTC']))
+
+ # Only test this if the underlying Time.at raises a TypeError
+ begin
+ Time.at_without_coercion(Time.now, 0)
+ rescue TypeError
+ assert_raise(TypeError) { assert_equal(Time.utc(2000, 1, 1, 0, 0, 0), Time.at(ActiveSupport::TimeWithZone.new(Time.utc(2000, 1, 1, 0, 0, 0), ActiveSupport::TimeZone['UTC']), 0)) }
+ end
+ end
+
def test_eql?
assert_equal true, Time.utc(2000).eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone['UTC']) )
assert_equal true, Time.utc(2000).eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone["Hawaii"]) )
diff --git a/activesupport/test/core_ext/time_with_zone_test.rb b/activesupport/test/core_ext/time_with_zone_test.rb
index 3ce3297874..ddcfcc491f 100644
--- a/activesupport/test/core_ext/time_with_zone_test.rb
+++ b/activesupport/test/core_ext/time_with_zone_test.rb
@@ -445,6 +445,16 @@ class TimeWithZoneTest < ActiveSupport::TestCase
assert_equal 0, twz.usec
end
+ def test_usec_returns_sec_fraction_when_datetime_is_wrapped
+ twz = ActiveSupport::TimeWithZone.new(DateTime.civil(2000, 1, 1, 0, 0, Rational(1,2)), @time_zone)
+ assert_equal 500000, twz.usec
+ end
+
+ def test_nsec_returns_sec_fraction_when_datetime_is_wrapped
+ twz = ActiveSupport::TimeWithZone.new(DateTime.civil(2000, 1, 1, 0, 0, Rational(1,2)), @time_zone)
+ assert_equal 500000000, twz.nsec
+ end
+
def test_utc_to_local_conversion_saves_period_in_instance_variable
assert_nil @twz.instance_variable_get('@period')
@twz.time
diff --git a/activesupport/test/dependencies/raises_exception_without_blame_file.rb b/activesupport/test/dependencies/raises_exception_without_blame_file.rb
new file mode 100644
index 0000000000..4b2da6ff30
--- /dev/null
+++ b/activesupport/test/dependencies/raises_exception_without_blame_file.rb
@@ -0,0 +1,5 @@
+exception = Exception.new('I am not blamable!')
+class << exception
+ undef_method(:blame_file!)
+end
+raise exception
diff --git a/activesupport/test/dependencies_test.rb b/activesupport/test/dependencies_test.rb
index 4b1426bb2e..68b6cc6e8c 100644
--- a/activesupport/test/dependencies_test.rb
+++ b/activesupport/test/dependencies_test.rb
@@ -76,6 +76,14 @@ class DependenciesTest < ActiveSupport::TestCase
end
end
+ def test_dependency_which_raises_doesnt_blindly_call_blame_file!
+ with_loading do
+ filename = 'dependencies/raises_exception_without_blame_file'
+
+ assert_raises(Exception) { require_dependency filename }
+ end
+ end
+
def test_warnings_should_be_enabled_on_first_load
with_loading 'dependencies' do
old_warnings, ActiveSupport::Dependencies.warnings_on_first_load = ActiveSupport::Dependencies.warnings_on_first_load, true
diff --git a/activesupport/test/load_paths_test.rb b/activesupport/test/load_paths_test.rb
index 979e25bdf3..ac617a9fd8 100644
--- a/activesupport/test/load_paths_test.rb
+++ b/activesupport/test/load_paths_test.rb
@@ -10,7 +10,7 @@ class LoadPathsTest < ActiveSupport::TestCase
}
load_paths_count[File.expand_path('../../lib', __FILE__)] -= 1
- filtered = load_paths_count.select { |k, v| v > 1 }
- assert filtered.empty?, filtered.inspect
+ load_paths_count.select! { |k, v| v > 1 }
+ assert load_paths_count.empty?, load_paths_count.inspect
end
end
diff --git a/activesupport/test/xml_mini/jdom_engine_test.rb b/activesupport/test/xml_mini/jdom_engine_test.rb
index 904ef7b208..ed4de8aba2 100644
--- a/activesupport/test/xml_mini/jdom_engine_test.rb
+++ b/activesupport/test/xml_mini/jdom_engine_test.rb
@@ -178,7 +178,7 @@ if RUBY_PLATFORM =~ /java/
private
def assert_equal_rexml(xml)
parsed_xml = XmlMini.parse(xml)
- hash = XmlMini.with_backend('REXML') { parsed_xml }
+ hash = XmlMini.with_backend('REXML') { XmlMini.parse(xml) }
assert_equal(hash, parsed_xml)
end
end
diff --git a/activesupport/test/xml_mini/libxml_engine_test.rb b/activesupport/test/xml_mini/libxml_engine_test.rb
index e7cb350663..a8df2e1f7b 100644
--- a/activesupport/test/xml_mini/libxml_engine_test.rb
+++ b/activesupport/test/xml_mini/libxml_engine_test.rb
@@ -195,7 +195,8 @@ class LibxmlEngineTest < ActiveSupport::TestCase
private
def assert_equal_rexml(xml)
parsed_xml = XmlMini.parse(xml)
- hash = XmlMini.with_backend('REXML') { parsed_xml }
+ xml.rewind if xml.respond_to?(:rewind)
+ hash = XmlMini.with_backend('REXML') { XmlMini.parse(xml) }
assert_equal(hash, parsed_xml)
end
end
diff --git a/activesupport/test/xml_mini/libxmlsax_engine_test.rb b/activesupport/test/xml_mini/libxmlsax_engine_test.rb
index 07485911c9..d6d90639e2 100644
--- a/activesupport/test/xml_mini/libxmlsax_engine_test.rb
+++ b/activesupport/test/xml_mini/libxmlsax_engine_test.rb
@@ -186,7 +186,8 @@ class LibXMLSAXEngineTest < ActiveSupport::TestCase
private
def assert_equal_rexml(xml)
parsed_xml = XmlMini.parse(xml)
- hash = XmlMini.with_backend('REXML') { parsed_xml }
+ xml.rewind if xml.respond_to?(:rewind)
+ hash = XmlMini.with_backend('REXML') { XmlMini.parse(xml) }
assert_equal(hash, parsed_xml)
end
end
diff --git a/activesupport/test/xml_mini/nokogiri_engine_test.rb b/activesupport/test/xml_mini/nokogiri_engine_test.rb
index 937517786e..2e962576b5 100644
--- a/activesupport/test/xml_mini/nokogiri_engine_test.rb
+++ b/activesupport/test/xml_mini/nokogiri_engine_test.rb
@@ -208,7 +208,8 @@ class NokogiriEngineTest < ActiveSupport::TestCase
private
def assert_equal_rexml(xml)
parsed_xml = XmlMini.parse(xml)
- hash = XmlMini.with_backend('REXML') { parsed_xml }
+ xml.rewind if xml.respond_to?(:rewind)
+ hash = XmlMini.with_backend('REXML') { XmlMini.parse(xml) }
assert_equal(hash, parsed_xml)
end
end
diff --git a/activesupport/test/xml_mini/nokogirisax_engine_test.rb b/activesupport/test/xml_mini/nokogirisax_engine_test.rb
index 84a5c44a87..4f078f31e0 100644
--- a/activesupport/test/xml_mini/nokogirisax_engine_test.rb
+++ b/activesupport/test/xml_mini/nokogirisax_engine_test.rb
@@ -209,7 +209,8 @@ class NokogiriSAXEngineTest < ActiveSupport::TestCase
private
def assert_equal_rexml(xml)
parsed_xml = XmlMini.parse(xml)
- hash = XmlMini.with_backend('REXML') { parsed_xml }
+ xml.rewind if xml.respond_to?(:rewind)
+ hash = XmlMini.with_backend('REXML') { XmlMini.parse(xml) }
assert_equal(hash, parsed_xml)
end
end
diff --git a/activesupport/test/xml_mini/rexml_engine_test.rb b/activesupport/test/xml_mini/rexml_engine_test.rb
index 70a3b918fd..0c1f11803c 100644
--- a/activesupport/test/xml_mini/rexml_engine_test.rb
+++ b/activesupport/test/xml_mini/rexml_engine_test.rb
@@ -30,7 +30,8 @@ class REXMLEngineTest < ActiveSupport::TestCase
private
def assert_equal_rexml(xml)
parsed_xml = XmlMini.parse(xml)
- hash = XmlMini.with_backend('REXML') { parsed_xml }
+ xml.rewind if xml.respond_to?(:rewind)
+ hash = XmlMini.with_backend('REXML') { XmlMini.parse(xml) }
assert_equal(hash, parsed_xml)
end
end