aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/CHANGELOG.md31
-rw-r--r--activesupport/lib/active_support/cache/file_store.rb16
-rw-r--r--activesupport/lib/active_support/core_ext/integer/multiple.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/string/output_safety.rb4
-rw-r--r--activesupport/lib/active_support/dependencies.rb25
-rw-r--r--activesupport/lib/active_support/i18n_railtie.rb14
-rw-r--r--activesupport/lib/active_support/tagged_logging.rb11
-rw-r--r--activesupport/lib/active_support/test_case.rb4
-rw-r--r--activesupport/lib/active_support/testing/parallelization.rb24
-rw-r--r--activesupport/lib/active_support/testing/time_helpers.rb3
-rw-r--r--activesupport/test/dependencies_test.rb49
-rw-r--r--activesupport/test/safe_buffer_test.rb12
-rw-r--r--activesupport/test/tagged_logging_test.rb29
-rw-r--r--activesupport/test/time_travel_test.rb4
14 files changed, 187 insertions, 41 deletions
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 4ae02edd6a..37bd4da15e 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,3 +1,30 @@
+* Changed `ActiveSupport::TaggedLogging.new` to return a new logger instance instead
+ of mutating the one received as parameter.
+
+ *Thierry Joyal*
+
+* Define `unfreeze_time` as an alias of `travel_back` in `ActiveSupport::Testing::TimeHelpers`.
+
+ The alias is provided for symmetry with `freeze_time`.
+
+ *Ryan Davidson*
+
+* Add support for tracing constant autoloads. Just throw
+
+ ActiveSupport::Dependencies.logger = Rails.logger
+ ActiveSupport::Dependencies.verbose = true
+
+ in an initializer.
+
+ *Xavier Noria*
+
+* Maintain `html_safe?` on html_safe strings when sliced.
+
+ string = "<div>test</div>".html_safe
+ string[-1..1].html_safe? # => true
+
+ *Elom Gomez*, *Yumin Wong*
+
* Add `Array#extract!`.
The method removes and returns the elements for which the block returns a true value.
@@ -50,7 +77,7 @@
*Aaron "t.lo" Patterson*
-* Add cpu_time, idle_time, and allocations to Event
+* Add cpu_time, idle_time, and allocations to Event.
*Eileen M. Uchitelle*, *Aaron Patterson*
@@ -64,7 +91,7 @@
*Jason Lee*
-* Allow Range#=== and Range#cover? on Range
+* Allow `Range#===` and `Range#cover?` on Range.
`Range#cover?` can now accept a range argument like `Range#include?` and
`Range#===`. `Range#===` works correctly on Ruby 2.6. `Range#include?` is moved
diff --git a/activesupport/lib/active_support/cache/file_store.rb b/activesupport/lib/active_support/cache/file_store.rb
index a0f44aac0f..04c54c30d0 100644
--- a/activesupport/lib/active_support/cache/file_store.rb
+++ b/activesupport/lib/active_support/cache/file_store.rb
@@ -127,15 +127,19 @@ module ActiveSupport
hash = Zlib.adler32(fname)
hash, dir_1 = hash.divmod(0x1000)
dir_2 = hash.modulo(0x1000)
- fname_paths = []
# Make sure file name doesn't exceed file system limits.
- begin
- fname_paths << fname[0, FILENAME_MAX_SIZE]
- fname = fname[FILENAME_MAX_SIZE..-1]
- end until fname.blank?
+ if fname.length < FILENAME_MAX_SIZE
+ fname_paths = fname
+ else
+ fname_paths = []
+ begin
+ fname_paths << fname[0, FILENAME_MAX_SIZE]
+ fname = fname[FILENAME_MAX_SIZE..-1]
+ end until fname.blank?
+ end
- File.join(cache_path, DIR_FORMATTER % dir_1, DIR_FORMATTER % dir_2, *fname_paths)
+ File.join(cache_path, DIR_FORMATTER % dir_1, DIR_FORMATTER % dir_2, fname_paths)
end
# Translate a file path into a key.
diff --git a/activesupport/lib/active_support/core_ext/integer/multiple.rb b/activesupport/lib/active_support/core_ext/integer/multiple.rb
index e7606662d3..bd57a909c5 100644
--- a/activesupport/lib/active_support/core_ext/integer/multiple.rb
+++ b/activesupport/lib/active_support/core_ext/integer/multiple.rb
@@ -7,6 +7,6 @@ class Integer
# 6.multiple_of?(5) # => false
# 10.multiple_of?(2) # => true
def multiple_of?(number)
- number != 0 ? self % number == 0 : zero?
+ number == 0 ? self == 0 : self % number == 0
end
end
diff --git a/activesupport/lib/active_support/core_ext/string/output_safety.rb b/activesupport/lib/active_support/core_ext/string/output_safety.rb
index f3bdc2977e..d837bb10aa 100644
--- a/activesupport/lib/active_support/core_ext/string/output_safety.rb
+++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb
@@ -149,9 +149,7 @@ module ActiveSupport #:nodoc:
end
def [](*args)
- if args.size < 2
- super
- elsif html_safe?
+ if html_safe?
new_safe_buffer = super
if new_safe_buffer
diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb
index 9dc2c46880..238a9f0ee6 100644
--- a/activesupport/lib/active_support/dependencies.rb
+++ b/activesupport/lib/active_support/dependencies.rb
@@ -79,6 +79,12 @@ module ActiveSupport #:nodoc:
# to allow arbitrary constants to be marked for unloading.
mattr_accessor :explicitly_unloadable_constants, default: []
+ # The logger used when tracing autoloads.
+ mattr_accessor :logger
+
+ # If true, trace autoloads with +logger.debug+.
+ mattr_accessor :verbose, default: false
+
# The WatchStack keeps a stack of the modules being watched as files are
# loaded. If a file in the process of being loaded (parent.rb) triggers the
# load of another file (child.rb) the stack will ensure that child.rb
@@ -416,7 +422,7 @@ module ActiveSupport #:nodoc:
# Search for a file in autoload_paths matching the provided suffix.
def search_for_file(path_suffix)
- path_suffix = path_suffix.sub(/(\.rb)?$/, ".rb".freeze)
+ path_suffix += ".rb" unless path_suffix.ends_with?(".rb")
autoload_paths.each do |root|
path = File.join(root, path_suffix)
@@ -450,6 +456,7 @@ module ActiveSupport #:nodoc:
return nil unless base_path = autoloadable_module?(path_suffix)
mod = Module.new
into.const_set const_name, mod
+ log("constant #{qualified_name} autoloaded (module autovivified from #{File.join(base_path, path_suffix)})")
autoloaded_constants << qualified_name unless autoload_once_paths.include?(base_path)
autoloaded_constants.uniq!
mod
@@ -491,7 +498,7 @@ module ActiveSupport #:nodoc:
raise ArgumentError, "A copy of #{from_mod} has been removed from the module tree but is still active!"
end
- qualified_name = qualified_name_for from_mod, const_name
+ qualified_name = qualified_name_for(from_mod, const_name)
path_suffix = qualified_name.underscore
file_path = search_for_file(path_suffix)
@@ -504,8 +511,13 @@ module ActiveSupport #:nodoc:
raise "Circular dependency detected while autoloading constant #{qualified_name}"
else
require_or_load(expanded, qualified_name)
- raise LoadError, "Unable to autoload constant #{qualified_name}, expected #{file_path} to define it" unless from_mod.const_defined?(const_name, false)
- return from_mod.const_get(const_name)
+
+ if from_mod.const_defined?(const_name, false)
+ log("constant #{qualified_name} autoloaded from #{expanded}.rb")
+ return from_mod.const_get(const_name)
+ else
+ raise LoadError, "Unable to autoload constant #{qualified_name}, expected #{file_path} to define it"
+ end
end
elsif mod = autoload_module!(from_mod, const_name, qualified_name, path_suffix)
return mod
@@ -554,6 +566,7 @@ module ActiveSupport #:nodoc:
# as the environment will be in an inconsistent state, e.g. other constants
# may have already been unloaded and not accessible.
def remove_unloadable_constants!
+ log("removing unloadable constants")
autoloaded_constants.each { |const| remove_constant const }
autoloaded_constants.clear
Reference.clear!
@@ -743,6 +756,10 @@ module ActiveSupport #:nodoc:
# The constant is no longer reachable, just skip it.
end
end
+
+ def log(message)
+ logger.debug("autoloading: #{message}") if logger && verbose
+ end
end
end
diff --git a/activesupport/lib/active_support/i18n_railtie.rb b/activesupport/lib/active_support/i18n_railtie.rb
index 93bde57f6a..584930e413 100644
--- a/activesupport/lib/active_support/i18n_railtie.rb
+++ b/activesupport/lib/active_support/i18n_railtie.rb
@@ -87,9 +87,21 @@ module I18n
when Hash, Array
Array.wrap(fallbacks)
else # TrueClass
- []
+ [I18n.default_locale]
end
+ if args.empty? || args.first.is_a?(Hash)
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
+ Using I18n fallbacks with an empty `defaults` sets the defaults to
+ include the `default_locale`. This behavior will change in Rails 6.1.
+ If you desire the default locale to be included in the defaults, please
+ explicitly configure it with `config.i18n.fallbacks.defaults =
+ [I18n.default_locale]` or `config.i18n.fallbacks = [I18n.default_locale,
+ {...}]`
+ MSG
+ args.unshift I18n.default_locale
+ end
+
I18n.fallbacks = I18n::Locale::Fallbacks.new(*args)
end
diff --git a/activesupport/lib/active_support/tagged_logging.rb b/activesupport/lib/active_support/tagged_logging.rb
index b069ac94d4..dd72da500c 100644
--- a/activesupport/lib/active_support/tagged_logging.rb
+++ b/activesupport/lib/active_support/tagged_logging.rb
@@ -61,8 +61,15 @@ module ActiveSupport
end
def self.new(logger)
- # Ensure we set a default formatter so we aren't extending nil!
- logger.formatter ||= ActiveSupport::Logger::SimpleFormatter.new
+ logger = logger.dup
+
+ if logger.formatter
+ logger.formatter = logger.formatter.dup
+ else
+ # Ensure we set a default formatter so we aren't extending nil!
+ logger.formatter = ActiveSupport::Logger::SimpleFormatter.new
+ end
+
logger.formatter.extend Formatter
logger.extend(self)
end
diff --git a/activesupport/lib/active_support/test_case.rb b/activesupport/lib/active_support/test_case.rb
index f17743b6db..ef12c6b9b0 100644
--- a/activesupport/lib/active_support/test_case.rb
+++ b/activesupport/lib/active_support/test_case.rb
@@ -65,8 +65,8 @@ module ActiveSupport
#
# parallelize(workers: 2, with: :threads)
#
- # The threaded parallelization uses Minitest's parallel executor directly.
- # The processes parallelization uses a Ruby Drb server.
+ # The threaded parallelization uses minitest's parallel executor directly.
+ # The processes parallelization uses a Ruby DRb server.
def parallelize(workers: 2, with: :processes)
workers = ENV["PARALLEL_WORKERS"].to_i if ENV["PARALLEL_WORKERS"]
diff --git a/activesupport/lib/active_support/testing/parallelization.rb b/activesupport/lib/active_support/testing/parallelization.rb
index 1caac1feb3..beeb470659 100644
--- a/activesupport/lib/active_support/testing/parallelization.rb
+++ b/activesupport/lib/active_support/testing/parallelization.rb
@@ -65,22 +65,24 @@ module ActiveSupport
def start
@pool = @queue_size.times.map do |worker|
fork do
- DRb.stop_service
+ begin
+ DRb.stop_service
- after_fork(worker)
+ after_fork(worker)
- queue = DRbObject.new_with_uri(@url)
+ queue = DRbObject.new_with_uri(@url)
- while job = queue.pop
- klass = job[0]
- method = job[1]
- reporter = job[2]
- result = Minitest.run_one_method(klass, method)
+ while job = queue.pop
+ klass = job[0]
+ method = job[1]
+ reporter = job[2]
+ result = Minitest.run_one_method(klass, method)
- queue.record(reporter, result)
+ queue.record(reporter, result)
+ end
+ ensure
+ run_cleanup(worker)
end
-
- run_cleanup(worker)
end
end
end
diff --git a/activesupport/lib/active_support/testing/time_helpers.rb b/activesupport/lib/active_support/testing/time_helpers.rb
index 801ea2909b..f160e66971 100644
--- a/activesupport/lib/active_support/testing/time_helpers.rb
+++ b/activesupport/lib/active_support/testing/time_helpers.rb
@@ -158,7 +158,7 @@ module ActiveSupport
end
# Returns the current time back to its original state, by removing the stubs added by
- # +travel+ and +travel_to+.
+ # +travel+, +travel_to+, and +freeze_time+.
#
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
# travel_to Time.zone.local(2004, 11, 24, 01, 04, 44)
@@ -168,6 +168,7 @@ module ActiveSupport
def travel_back
simple_stubs.unstub_all!
end
+ alias_method :unfreeze_time, :travel_back
# Calls +travel_to+ with +Time.now+.
#
diff --git a/activesupport/test/dependencies_test.rb b/activesupport/test/dependencies_test.rb
index 84cb64a7c2..a486ef5eac 100644
--- a/activesupport/test/dependencies_test.rb
+++ b/activesupport/test/dependencies_test.rb
@@ -1130,3 +1130,52 @@ class DependenciesTest < ActiveSupport::TestCase
ActiveSupport::Dependencies.hook!
end
end
+
+class DependenciesLogging < ActiveSupport::TestCase
+ MESSAGE = "message"
+
+ def with_settings(logger, verbose)
+ original_logger = ActiveSupport::Dependencies.logger
+ original_verbose = ActiveSupport::Dependencies.verbose
+
+ ActiveSupport::Dependencies.logger = logger
+ ActiveSupport::Dependencies.verbose = verbose
+
+ yield
+ ensure
+ ActiveSupport::Dependencies.logger = original_logger
+ ActiveSupport::Dependencies.verbose = original_verbose
+ end
+
+ def fake_logger
+ Class.new do
+ def self.debug(message)
+ message
+ end
+ end
+ end
+
+ test "does not log if the logger is nil and verbose is false" do
+ with_settings(nil, false) do
+ assert_nil ActiveSupport::Dependencies.log(MESSAGE)
+ end
+ end
+
+ test "does not log if the logger is nil and verbose is true" do
+ with_settings(nil, true) do
+ assert_nil ActiveSupport::Dependencies.log(MESSAGE)
+ end
+ end
+
+ test "does not log if the logger is set and verbose is false" do
+ with_settings(fake_logger, false) do
+ assert_nil ActiveSupport::Dependencies.log(MESSAGE)
+ end
+ end
+
+ test "logs if the logger is set and verbose is true" do
+ with_settings(fake_logger, true) do
+ assert_equal "autoloading: #{MESSAGE}", ActiveSupport::Dependencies.log(MESSAGE)
+ end
+ end
+end
diff --git a/activesupport/test/safe_buffer_test.rb b/activesupport/test/safe_buffer_test.rb
index 9456bb8753..70dec6b3d2 100644
--- a/activesupport/test/safe_buffer_test.rb
+++ b/activesupport/test/safe_buffer_test.rb
@@ -150,6 +150,18 @@ class SafeBufferTest < ActiveSupport::TestCase
assert_not y.html_safe?, "should not be safe"
end
+ test "Should continue safe on slice" do
+ x = "<div>foo</div>".html_safe
+
+ assert_predicate x, :html_safe?
+
+ # getting a slice of it
+ y = x[0..-1]
+
+ # should still be safe
+ assert_predicate y, :html_safe?
+ end
+
test "Should work with interpolation (array argument)" do
x = "foo %s bar".html_safe % ["qux"]
assert_equal "foo qux bar", x
diff --git a/activesupport/test/tagged_logging_test.rb b/activesupport/test/tagged_logging_test.rb
index e2b41cf8ee..cff73472c3 100644
--- a/activesupport/test/tagged_logging_test.rb
+++ b/activesupport/test/tagged_logging_test.rb
@@ -19,9 +19,10 @@ class TaggedLoggingTest < ActiveSupport::TestCase
test "sets logger.formatter if missing and extends it with a tagging API" do
logger = Logger.new(StringIO.new)
assert_nil logger.formatter
- ActiveSupport::TaggedLogging.new(logger)
- assert_not_nil logger.formatter
- assert_respond_to logger.formatter, :tagged
+
+ other_logger = ActiveSupport::TaggedLogging.new(logger)
+ assert_not_nil other_logger.formatter
+ assert_respond_to other_logger.formatter, :tagged
end
test "tagged once" do
@@ -83,16 +84,28 @@ class TaggedLoggingTest < ActiveSupport::TestCase
end
test "keeps each tag in their own instance" do
- @other_output = StringIO.new
- @other_logger = ActiveSupport::TaggedLogging.new(MyLogger.new(@other_output))
+ other_output = StringIO.new
+ other_logger = ActiveSupport::TaggedLogging.new(MyLogger.new(other_output))
@logger.tagged("OMG") do
- @other_logger.tagged("BCX") do
+ other_logger.tagged("BCX") do
@logger.info "Cool story"
- @other_logger.info "Funky time"
+ other_logger.info "Funky time"
end
end
assert_equal "[OMG] Cool story\n", @output.string
- assert_equal "[BCX] Funky time\n", @other_output.string
+ assert_equal "[BCX] Funky time\n", other_output.string
+ end
+
+ test "does not share the same formatter instance of the original logger" do
+ other_logger = ActiveSupport::TaggedLogging.new(@logger)
+
+ @logger.tagged("OMG") do
+ other_logger.tagged("BCX") do
+ @logger.info "Cool story"
+ other_logger.info "Funky time"
+ end
+ end
+ assert_equal "[OMG] Cool story\n[BCX] Funky time\n", @output.string
end
test "cleans up the taggings on flush" do
diff --git a/activesupport/test/time_travel_test.rb b/activesupport/test/time_travel_test.rb
index 9c2c635f43..8c47f2cdc7 100644
--- a/activesupport/test/time_travel_test.rb
+++ b/activesupport/test/time_travel_test.rb
@@ -186,4 +186,8 @@ class TimeTravelTest < ActiveSupport::TestCase
assert_operator expected_time.to_s(:db), :<, Time.now.to_s(:db)
end
+
+ def test_time_helper_unfreeze_time
+ assert_equal method(:travel_back), method(:unfreeze_time)
+ end
end