activesupport 6.1.4.1 → 7.0.8.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +325 -395
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -2
- data/lib/active_support/actionable_error.rb +1 -1
- data/lib/active_support/array_inquirer.rb +0 -2
- data/lib/active_support/backtrace_cleaner.rb +2 -2
- data/lib/active_support/benchmarkable.rb +2 -2
- data/lib/active_support/cache/file_store.rb +15 -9
- data/lib/active_support/cache/mem_cache_store.rb +148 -37
- data/lib/active_support/cache/memory_store.rb +24 -16
- data/lib/active_support/cache/null_store.rb +10 -2
- data/lib/active_support/cache/redis_cache_store.rb +68 -85
- data/lib/active_support/cache/strategy/local_cache.rb +38 -61
- data/lib/active_support/cache.rb +299 -147
- data/lib/active_support/callbacks.rb +184 -85
- data/lib/active_support/code_generator.rb +65 -0
- data/lib/active_support/concern.rb +5 -5
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +2 -4
- data/lib/active_support/concurrency/share_lock.rb +2 -2
- data/lib/active_support/configurable.rb +8 -5
- data/lib/active_support/configuration_file.rb +1 -1
- data/lib/active_support/core_ext/array/access.rb +1 -5
- data/lib/active_support/core_ext/array/conversions.rb +13 -12
- data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
- data/lib/active_support/core_ext/array/grouping.rb +6 -6
- data/lib/active_support/core_ext/array/inquiry.rb +2 -2
- data/lib/active_support/core_ext/array.rb +1 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +1 -1
- data/lib/active_support/core_ext/class/subclasses.rb +25 -17
- data/lib/active_support/core_ext/date/blank.rb +1 -1
- data/lib/active_support/core_ext/date/calculations.rb +24 -9
- data/lib/active_support/core_ext/date/conversions.rb +14 -14
- data/lib/active_support/core_ext/date/deprecated_conversions.rb +40 -0
- data/lib/active_support/core_ext/date.rb +1 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +4 -4
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +1 -1
- data/lib/active_support/core_ext/date_time/blank.rb +1 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +4 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +13 -13
- data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +36 -0
- data/lib/active_support/core_ext/date_time.rb +1 -0
- data/lib/active_support/core_ext/digest/uuid.rb +39 -13
- data/lib/active_support/core_ext/enumerable.rb +112 -38
- data/lib/active_support/core_ext/file/atomic.rb +3 -1
- data/lib/active_support/core_ext/hash/conversions.rb +0 -1
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +3 -3
- data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
- data/lib/active_support/core_ext/hash/keys.rb +4 -4
- data/lib/active_support/core_ext/integer/inflections.rb +12 -12
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -4
- data/lib/active_support/core_ext/kernel/singleton_class.rb +1 -1
- data/lib/active_support/core_ext/module/attribute_accessors.rb +2 -0
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +19 -10
- data/lib/active_support/core_ext/module/delegation.rb +2 -8
- data/lib/active_support/core_ext/name_error.rb +2 -8
- data/lib/active_support/core_ext/numeric/conversions.rb +80 -77
- data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
- data/lib/active_support/core_ext/numeric.rb +1 -0
- data/lib/active_support/core_ext/object/acts_like.rb +29 -5
- data/lib/active_support/core_ext/object/blank.rb +2 -2
- data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
- data/lib/active_support/core_ext/object/duplicable.rb +15 -4
- data/lib/active_support/core_ext/object/json.rb +30 -25
- data/lib/active_support/core_ext/object/to_query.rb +2 -4
- data/lib/active_support/core_ext/object/try.rb +20 -20
- data/lib/active_support/core_ext/object/with_options.rb +21 -2
- data/lib/active_support/core_ext/pathname/existence.rb +21 -0
- data/lib/active_support/core_ext/pathname.rb +3 -0
- data/lib/active_support/core_ext/range/compare_range.rb +0 -25
- data/lib/active_support/core_ext/range/conversions.rb +8 -8
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +36 -0
- data/lib/active_support/core_ext/range/each.rb +1 -1
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +3 -26
- data/lib/active_support/core_ext/range/overlaps.rb +1 -1
- data/lib/active_support/core_ext/range.rb +1 -1
- data/lib/active_support/core_ext/securerandom.rb +1 -1
- data/lib/active_support/core_ext/string/conversions.rb +2 -2
- data/lib/active_support/core_ext/string/filters.rb +1 -1
- data/lib/active_support/core_ext/string/inflections.rb +1 -5
- data/lib/active_support/core_ext/string/inquiry.rb +1 -1
- data/lib/active_support/core_ext/string/output_safety.rb +94 -38
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +0 -8
- data/lib/active_support/core_ext/time/calculations.rb +13 -8
- data/lib/active_support/core_ext/time/conversions.rb +13 -12
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +73 -0
- data/lib/active_support/core_ext/time/zones.rb +10 -26
- data/lib/active_support/core_ext/time.rb +1 -0
- data/lib/active_support/core_ext/uri.rb +3 -27
- data/lib/active_support/core_ext.rb +1 -0
- data/lib/active_support/current_attributes.rb +31 -14
- data/lib/active_support/dependencies/interlock.rb +10 -18
- data/lib/active_support/dependencies/require_dependency.rb +28 -0
- data/lib/active_support/dependencies.rb +58 -788
- data/lib/active_support/deprecation/behaviors.rb +8 -5
- data/lib/active_support/deprecation/disallowed.rb +3 -3
- data/lib/active_support/deprecation/method_wrappers.rb +3 -3
- data/lib/active_support/deprecation/proxy_wrappers.rb +2 -2
- data/lib/active_support/deprecation.rb +2 -2
- data/lib/active_support/descendants_tracker.rb +174 -68
- data/lib/active_support/digest.rb +5 -3
- data/lib/active_support/duration/iso8601_parser.rb +3 -3
- data/lib/active_support/duration/iso8601_serializer.rb +9 -1
- data/lib/active_support/duration.rb +81 -51
- data/lib/active_support/encrypted_configuration.rb +45 -3
- data/lib/active_support/encrypted_file.rb +21 -10
- data/lib/active_support/environment_inquirer.rb +1 -1
- data/lib/active_support/error_reporter.rb +117 -0
- data/lib/active_support/evented_file_update_checker.rb +20 -7
- data/lib/active_support/execution_context/test_helper.rb +13 -0
- data/lib/active_support/execution_context.rb +53 -0
- data/lib/active_support/execution_wrapper.rb +43 -21
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/fork_tracker.rb +19 -12
- data/lib/active_support/gem_version.rb +5 -5
- data/lib/active_support/hash_with_indifferent_access.rb +3 -1
- data/lib/active_support/html_safe_translation.rb +43 -0
- data/lib/active_support/i18n.rb +1 -0
- data/lib/active_support/i18n_railtie.rb +1 -1
- data/lib/active_support/inflector/inflections.rb +23 -7
- data/lib/active_support/inflector/methods.rb +29 -55
- data/lib/active_support/inflector/transliterate.rb +1 -1
- data/lib/active_support/isolated_execution_state.rb +72 -0
- data/lib/active_support/json/encoding.rb +3 -3
- data/lib/active_support/key_generator.rb +22 -5
- data/lib/active_support/lazy_load_hooks.rb +28 -4
- data/lib/active_support/locale/en.yml +1 -1
- data/lib/active_support/log_subscriber/test_helper.rb +2 -2
- data/lib/active_support/log_subscriber.rb +15 -5
- data/lib/active_support/logger_thread_safe_level.rb +4 -13
- data/lib/active_support/message_encryptor.rb +12 -6
- data/lib/active_support/message_verifier.rb +46 -14
- data/lib/active_support/messages/metadata.rb +2 -2
- data/lib/active_support/multibyte/chars.rb +10 -11
- data/lib/active_support/multibyte/unicode.rb +0 -12
- data/lib/active_support/multibyte.rb +1 -1
- data/lib/active_support/notifications/fanout.rb +91 -65
- data/lib/active_support/notifications/instrumenter.rb +32 -15
- data/lib/active_support/notifications.rb +23 -23
- data/lib/active_support/number_helper/number_converter.rb +1 -3
- data/lib/active_support/number_helper/number_to_currency_converter.rb +11 -6
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -1
- data/lib/active_support/number_helper/rounding_helper.rb +1 -5
- data/lib/active_support/number_helper.rb +4 -5
- data/lib/active_support/option_merger.rb +10 -18
- data/lib/active_support/ordered_hash.rb +1 -1
- data/lib/active_support/ordered_options.rb +1 -1
- data/lib/active_support/parameter_filter.rb +20 -11
- data/lib/active_support/per_thread_registry.rb +5 -0
- data/lib/active_support/railtie.rb +69 -19
- data/lib/active_support/reloader.rb +1 -1
- data/lib/active_support/rescuable.rb +12 -12
- data/lib/active_support/ruby_features.rb +7 -0
- data/lib/active_support/secure_compare_rotator.rb +2 -2
- data/lib/active_support/string_inquirer.rb +0 -2
- data/lib/active_support/subscriber.rb +7 -18
- data/lib/active_support/tagged_logging.rb +2 -2
- data/lib/active_support/test_case.rb +13 -21
- data/lib/active_support/testing/assertions.rb +36 -6
- data/lib/active_support/testing/deprecation.rb +52 -1
- data/lib/active_support/testing/isolation.rb +30 -29
- data/lib/active_support/testing/method_call_assertions.rb +5 -5
- data/lib/active_support/testing/parallelization/server.rb +4 -0
- data/lib/active_support/testing/parallelization/worker.rb +3 -0
- data/lib/active_support/testing/parallelization.rb +4 -0
- data/lib/active_support/testing/parallelize_executor.rb +76 -0
- data/lib/active_support/testing/stream.rb +3 -5
- data/lib/active_support/testing/tagged_logging.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +13 -2
- data/lib/active_support/time_with_zone.rb +43 -22
- data/lib/active_support/values/time_zone.rb +35 -14
- data/lib/active_support/version.rb +1 -1
- data/lib/active_support/xml_mini/jdom.rb +1 -1
- data/lib/active_support/xml_mini/libxml.rb +5 -5
- data/lib/active_support/xml_mini/libxmlsax.rb +1 -1
- data/lib/active_support/xml_mini/nokogiri.rb +4 -4
- data/lib/active_support/xml_mini/nokogirisax.rb +1 -1
- data/lib/active_support/xml_mini/rexml.rb +1 -1
- data/lib/active_support/xml_mini.rb +5 -4
- data/lib/active_support.rb +17 -1
- metadata +26 -23
- data/lib/active_support/core_ext/marshal.rb +0 -26
- data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -117
@@ -5,7 +5,7 @@ module ActiveSupport
|
|
5
5
|
module Isolation
|
6
6
|
require "thread"
|
7
7
|
|
8
|
-
def self.included(klass)
|
8
|
+
def self.included(klass) # :nodoc:
|
9
9
|
klass.class_eval do
|
10
10
|
parallelize_me!
|
11
11
|
end
|
@@ -25,45 +25,46 @@ module ActiveSupport
|
|
25
25
|
|
26
26
|
module Forking
|
27
27
|
def run_in_isolation(&blk)
|
28
|
-
read, write
|
29
|
-
|
30
|
-
|
28
|
+
IO.pipe do |read, write|
|
29
|
+
read.binmode
|
30
|
+
write.binmode
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
32
|
+
pid = fork do
|
33
|
+
read.close
|
34
|
+
yield
|
35
|
+
begin
|
36
|
+
if error?
|
37
|
+
failures.map! { |e|
|
38
|
+
begin
|
39
|
+
Marshal.dump e
|
40
|
+
e
|
41
|
+
rescue TypeError
|
42
|
+
ex = Exception.new e.message
|
43
|
+
ex.set_backtrace e.backtrace
|
44
|
+
Minitest::UnexpectedError.new ex
|
45
|
+
end
|
46
|
+
}
|
47
|
+
end
|
48
|
+
test_result = defined?(Minitest::Result) ? Minitest::Result.from(self) : dup
|
49
|
+
result = Marshal.dump(test_result)
|
47
50
|
end
|
48
|
-
|
49
|
-
result
|
51
|
+
|
52
|
+
write.puts [result].pack("m")
|
53
|
+
exit!
|
50
54
|
end
|
51
55
|
|
52
|
-
write.
|
53
|
-
|
56
|
+
write.close
|
57
|
+
result = read.read
|
58
|
+
Process.wait2(pid)
|
59
|
+
result.unpack1("m")
|
54
60
|
end
|
55
|
-
|
56
|
-
write.close
|
57
|
-
result = read.read
|
58
|
-
Process.wait2(pid)
|
59
|
-
result.unpack1("m")
|
60
61
|
end
|
61
62
|
end
|
62
63
|
|
63
64
|
module Subprocess
|
64
65
|
ORIG_ARGV = ARGV.dup unless defined?(ORIG_ARGV)
|
65
66
|
|
66
|
-
#
|
67
|
+
# Complicated H4X to get this working in windows / jruby with
|
67
68
|
# no forking.
|
68
69
|
def run_in_isolation(&blk)
|
69
70
|
require "tempfile"
|
@@ -6,10 +6,10 @@ module ActiveSupport
|
|
6
6
|
module Testing
|
7
7
|
module MethodCallAssertions # :nodoc:
|
8
8
|
private
|
9
|
-
def assert_called(object, method_name, message = nil, times: 1, returns: nil)
|
9
|
+
def assert_called(object, method_name, message = nil, times: 1, returns: nil, &block)
|
10
10
|
times_called = 0
|
11
11
|
|
12
|
-
object.stub(method_name, proc { times_called += 1; returns })
|
12
|
+
object.stub(method_name, proc { times_called += 1; returns }, &block)
|
13
13
|
|
14
14
|
error = "Expected #{method_name} to be called #{times} times, " \
|
15
15
|
"but was called #{times_called} times"
|
@@ -17,16 +17,16 @@ module ActiveSupport
|
|
17
17
|
assert_equal times, times_called, error
|
18
18
|
end
|
19
19
|
|
20
|
-
def assert_called_with(object, method_name, args, returns: nil)
|
20
|
+
def assert_called_with(object, method_name, args, returns: nil, &block)
|
21
21
|
mock = Minitest::Mock.new
|
22
22
|
|
23
|
-
if args.all?
|
23
|
+
if args.all?(Array)
|
24
24
|
args.each { |arg| mock.expect(:call, returns, arg) }
|
25
25
|
else
|
26
26
|
mock.expect(:call, returns, args)
|
27
27
|
end
|
28
28
|
|
29
|
-
object.stub(method_name, mock)
|
29
|
+
object.stub(method_name, mock, &block)
|
30
30
|
|
31
31
|
mock.verify
|
32
32
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveSupport
|
4
|
+
module Testing
|
5
|
+
class ParallelizeExecutor # :nodoc:
|
6
|
+
attr_reader :size, :parallelize_with, :threshold
|
7
|
+
|
8
|
+
def initialize(size:, with:, threshold: ActiveSupport.test_parallelization_threshold)
|
9
|
+
@size = size
|
10
|
+
@parallelize_with = with
|
11
|
+
@threshold = threshold
|
12
|
+
end
|
13
|
+
|
14
|
+
def start
|
15
|
+
parallelize if should_parallelize?
|
16
|
+
show_execution_info
|
17
|
+
|
18
|
+
parallel_executor.start if parallelized?
|
19
|
+
end
|
20
|
+
|
21
|
+
def <<(work)
|
22
|
+
parallel_executor << work if parallelized?
|
23
|
+
end
|
24
|
+
|
25
|
+
def shutdown
|
26
|
+
parallel_executor.shutdown if parallelized?
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
def parallel_executor
|
31
|
+
@parallel_executor ||= build_parallel_executor
|
32
|
+
end
|
33
|
+
|
34
|
+
def build_parallel_executor
|
35
|
+
case parallelize_with
|
36
|
+
when :processes
|
37
|
+
Testing::Parallelization.new(size)
|
38
|
+
when :threads
|
39
|
+
ActiveSupport::TestCase.lock_threads = false if defined?(ActiveSupport::TestCase.lock_threads)
|
40
|
+
Minitest::Parallel::Executor.new(size)
|
41
|
+
else
|
42
|
+
raise ArgumentError, "#{parallelize_with} is not a supported parallelization executor."
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def parallelize
|
47
|
+
@parallelized = true
|
48
|
+
Minitest::Test.parallelize_me!
|
49
|
+
end
|
50
|
+
|
51
|
+
def parallelized?
|
52
|
+
@parallelized if defined?(@parallelized)
|
53
|
+
end
|
54
|
+
|
55
|
+
def should_parallelize?
|
56
|
+
ENV["PARALLEL_WORKERS"] || tests_count > threshold
|
57
|
+
end
|
58
|
+
|
59
|
+
def tests_count
|
60
|
+
@tests_count ||= Minitest::Runnable.runnables.sum { |runnable| runnable.runnable_methods.size }
|
61
|
+
end
|
62
|
+
|
63
|
+
def show_execution_info
|
64
|
+
puts execution_info
|
65
|
+
end
|
66
|
+
|
67
|
+
def execution_info
|
68
|
+
if parallelized?
|
69
|
+
"Running #{tests_count} tests in parallel using #{parallel_executor.size} #{parallelize_with}"
|
70
|
+
else
|
71
|
+
"Running #{tests_count} tests in a single process (parallelization threshold is #{threshold})"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module ActiveSupport
|
4
4
|
module Testing
|
5
|
-
module Stream
|
5
|
+
module Stream # :nodoc:
|
6
6
|
private
|
7
7
|
def silence_stream(stream)
|
8
8
|
old_stream = stream.dup
|
@@ -14,11 +14,9 @@ module ActiveSupport
|
|
14
14
|
old_stream.close
|
15
15
|
end
|
16
16
|
|
17
|
-
def quietly
|
17
|
+
def quietly(&block)
|
18
18
|
silence_stream(STDOUT) do
|
19
|
-
silence_stream(STDERR)
|
20
|
-
yield
|
21
|
-
end
|
19
|
+
silence_stream(STDERR, &block)
|
22
20
|
end
|
23
21
|
end
|
24
22
|
|
@@ -4,7 +4,7 @@ module ActiveSupport
|
|
4
4
|
module Testing
|
5
5
|
# Logs a "PostsControllerTest: test name" heading before each test to
|
6
6
|
# make test.log easier to search and follow along with.
|
7
|
-
module TaggedLogging
|
7
|
+
module TaggedLogging # :nodoc:
|
8
8
|
attr_writer :tagged_logger
|
9
9
|
|
10
10
|
def before_setup
|
@@ -126,7 +126,7 @@ module ActiveSupport
|
|
126
126
|
# end
|
127
127
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
128
128
|
def travel_to(date_or_time)
|
129
|
-
if block_given? &&
|
129
|
+
if block_given? && in_block
|
130
130
|
travel_to_nested_block_call = <<~MSG
|
131
131
|
|
132
132
|
Calling `travel_to` with a block, when we have previously already made a call to `travel_to`, can lead to confusing time stubbing.
|
@@ -156,19 +156,28 @@ module ActiveSupport
|
|
156
156
|
|
157
157
|
if date_or_time.is_a?(Date) && !date_or_time.is_a?(DateTime)
|
158
158
|
now = date_or_time.midnight.to_time
|
159
|
+
elsif date_or_time.is_a?(String)
|
160
|
+
now = Time.zone.parse(date_or_time)
|
159
161
|
else
|
160
162
|
now = date_or_time.to_time.change(usec: 0)
|
161
163
|
end
|
162
164
|
|
165
|
+
stubbed_time = Time.now if simple_stubs.stubbing(Time, :now)
|
163
166
|
simple_stubs.stub_object(Time, :now) { at(now.to_i) }
|
164
167
|
simple_stubs.stub_object(Date, :today) { jd(now.to_date.jd) }
|
165
168
|
simple_stubs.stub_object(DateTime, :now) { jd(now.to_date.jd, now.hour, now.min, now.sec, Rational(now.utc_offset, 86400)) }
|
166
169
|
|
167
170
|
if block_given?
|
168
171
|
begin
|
172
|
+
self.in_block = true
|
169
173
|
yield
|
170
174
|
ensure
|
171
|
-
|
175
|
+
if stubbed_time
|
176
|
+
travel_to stubbed_time
|
177
|
+
else
|
178
|
+
travel_back
|
179
|
+
end
|
180
|
+
self.in_block = false
|
172
181
|
end
|
173
182
|
end
|
174
183
|
end
|
@@ -230,6 +239,8 @@ module ActiveSupport
|
|
230
239
|
def simple_stubs
|
231
240
|
@simple_stubs ||= SimpleStubs.new
|
232
241
|
end
|
242
|
+
|
243
|
+
attr_accessor :in_block
|
233
244
|
end
|
234
245
|
end
|
235
246
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "yaml"
|
4
|
+
|
3
5
|
require "active_support/duration"
|
4
6
|
require "active_support/values/time_zone"
|
5
7
|
require "active_support/core_ext/object/acts_like"
|
@@ -11,7 +13,7 @@ module ActiveSupport
|
|
11
13
|
# system's <tt>ENV['TZ']</tt> zone.
|
12
14
|
#
|
13
15
|
# You shouldn't ever need to create a TimeWithZone instance directly via +new+.
|
14
|
-
# Instead use methods +local+, +parse+, +at
|
16
|
+
# Instead use methods +local+, +parse+, +at+, and +now+ on TimeZone instances,
|
15
17
|
# and +in_time_zone+ on Time and DateTime instances.
|
16
18
|
#
|
17
19
|
# Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
|
@@ -31,7 +33,7 @@ module ActiveSupport
|
|
31
33
|
# t.dst? # => true
|
32
34
|
# t.utc_offset # => -14400
|
33
35
|
# t.zone # => "EDT"
|
34
|
-
# t.
|
36
|
+
# t.to_fs(:rfc822) # => "Sun, 18 May 2008 13:27:25 -0400"
|
35
37
|
# t + 1.day # => Mon, 19 May 2008 13:27:25.031505668 EDT -04:00
|
36
38
|
# t.beginning_of_year # => Tue, 01 Jan 2008 00:00:00.000000000 EST -05:00
|
37
39
|
# t > Time.utc(1999) # => true
|
@@ -40,6 +42,13 @@ module ActiveSupport
|
|
40
42
|
class TimeWithZone
|
41
43
|
# Report class name as 'Time' to thwart type checking.
|
42
44
|
def self.name
|
45
|
+
ActiveSupport::Deprecation.warn(<<~EOM)
|
46
|
+
ActiveSupport::TimeWithZone.name has been deprecated and
|
47
|
+
from Rails 7.1 will use the default Ruby implementation.
|
48
|
+
You can set `config.active_support.remove_deprecated_time_with_zone_name = true`
|
49
|
+
to enable the new behavior now.
|
50
|
+
EOM
|
51
|
+
|
43
52
|
"Time"
|
44
53
|
end
|
45
54
|
|
@@ -69,7 +78,7 @@ module ActiveSupport
|
|
69
78
|
alias_method :getutc, :utc
|
70
79
|
alias_method :gmtime, :utc
|
71
80
|
|
72
|
-
# Returns the underlying TZInfo::TimezonePeriod
|
81
|
+
# Returns the underlying <tt>TZInfo::TimezonePeriod</tt>.
|
73
82
|
def period
|
74
83
|
@period ||= time_zone.period_for_utc(@utc)
|
75
84
|
end
|
@@ -172,12 +181,11 @@ module ActiveSupport
|
|
172
181
|
end
|
173
182
|
end
|
174
183
|
|
175
|
-
def init_with(coder)
|
184
|
+
def init_with(coder) # :nodoc:
|
176
185
|
initialize(coder["utc"], coder["zone"], coder["time"])
|
177
186
|
end
|
178
187
|
|
179
|
-
def encode_with(coder)
|
180
|
-
coder.tag = "!ruby/object:ActiveSupport::TimeWithZone"
|
188
|
+
def encode_with(coder) # :nodoc:
|
181
189
|
coder.map = { "utc" => utc, "zone" => time_zone, "time" => time }
|
182
190
|
end
|
183
191
|
|
@@ -194,25 +202,34 @@ module ActiveSupport
|
|
194
202
|
#
|
195
203
|
# Time.zone.now.rfc2822 # => "Tue, 01 Jan 2013 04:51:39 +0000"
|
196
204
|
def rfc2822
|
197
|
-
|
205
|
+
to_fs(:rfc822)
|
198
206
|
end
|
199
207
|
alias_method :rfc822, :rfc2822
|
200
208
|
|
201
209
|
# Returns a string of the object's date and time.
|
210
|
+
def to_s
|
211
|
+
"#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}" # mimicking Ruby Time#to_s format
|
212
|
+
end
|
213
|
+
|
214
|
+
# Returns a string of the object's date and time.
|
215
|
+
#
|
216
|
+
# This method is aliased to <tt>to_formatted_s</tt>.
|
217
|
+
#
|
202
218
|
# Accepts an optional <tt>format</tt>:
|
203
219
|
# * <tt>:default</tt> - default value, mimics Ruby Time#to_s format.
|
204
|
-
# * <tt>:db</tt> - format outputs time in UTC :db time. See Time#
|
220
|
+
# * <tt>:db</tt> - format outputs time in UTC :db time. See Time#to_fs(:db).
|
205
221
|
# * Any key in <tt>Time::DATE_FORMATS</tt> can be used. See active_support/core_ext/time/conversions.rb.
|
206
|
-
def
|
222
|
+
def to_fs(format = :default)
|
207
223
|
if format == :db
|
208
|
-
utc.
|
224
|
+
utc.to_fs(format)
|
209
225
|
elsif formatter = ::Time::DATE_FORMATS[format]
|
210
226
|
formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
|
211
227
|
else
|
212
|
-
|
228
|
+
# Change to to_s when deprecation is gone.
|
229
|
+
"#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}"
|
213
230
|
end
|
214
231
|
end
|
215
|
-
alias_method :to_formatted_s, :
|
232
|
+
alias_method :to_formatted_s, :to_fs
|
216
233
|
|
217
234
|
# Replaces <tt>%Z</tt> directive with +zone before passing to Time#strftime,
|
218
235
|
# so that zone information is correct.
|
@@ -301,9 +318,8 @@ module ActiveSupport
|
|
301
318
|
alias_method :in, :+
|
302
319
|
|
303
320
|
# Subtracts an interval of time and returns a new TimeWithZone object unless
|
304
|
-
# the other value +acts_like?+ time.
|
305
|
-
#
|
306
|
-
# object's time and the +other+ time.
|
321
|
+
# the other value +acts_like?+ time. In which case, it will subtract the
|
322
|
+
# other time and return the difference in seconds as a Float.
|
307
323
|
#
|
308
324
|
# Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
|
309
325
|
# now = Time.zone.now # => Mon, 03 Nov 2014 00:26:28.725182881 EST -05:00
|
@@ -359,8 +375,8 @@ module ActiveSupport
|
|
359
375
|
# Returns a new +ActiveSupport::TimeWithZone+ where one or more of the elements have
|
360
376
|
# been changed according to the +options+ parameter. The time options (<tt>:hour</tt>,
|
361
377
|
# <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly,
|
362
|
-
# so if only the hour is passed, then minute, sec, usec and nsec is set to 0. If the
|
363
|
-
# hour and minute is passed, then sec, usec and nsec is set to 0. The +options+
|
378
|
+
# so if only the hour is passed, then minute, sec, usec, and nsec is set to 0. If the
|
379
|
+
# hour and minute is passed, then sec, usec, and nsec is set to 0. The +options+
|
364
380
|
# parameter takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>,
|
365
381
|
# <tt>:day</tt>, <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>,
|
366
382
|
# <tt>:nsec</tt>, <tt>:offset</tt>, <tt>:zone</tt>. Pass either <tt>:usec</tt>
|
@@ -440,7 +456,7 @@ module ActiveSupport
|
|
440
456
|
[time.sec, time.min, time.hour, time.day, time.mon, time.year, time.wday, time.yday, dst?, zone]
|
441
457
|
end
|
442
458
|
|
443
|
-
# Returns the object's date and time as a floating
|
459
|
+
# Returns the object's date and time as a floating-point number of seconds
|
444
460
|
# since the Epoch (January 1, 1970 00:00 UTC).
|
445
461
|
#
|
446
462
|
# Time.zone.now.to_f # => 1417709320.285418
|
@@ -531,10 +547,10 @@ module ActiveSupport
|
|
531
547
|
|
532
548
|
# Send the missing method to +time+ instance, and wrap result in a new
|
533
549
|
# TimeWithZone with the existing +time_zone+.
|
534
|
-
def method_missing(
|
535
|
-
wrap_with_time_zone time.__send__(
|
550
|
+
def method_missing(...)
|
551
|
+
wrap_with_time_zone time.__send__(...)
|
536
552
|
rescue NoMethodError => e
|
537
|
-
raise e, e.message.sub(time.inspect, inspect), e.backtrace
|
553
|
+
raise e, e.message.sub(time.inspect, inspect).sub("Time", "ActiveSupport::TimeWithZone"), e.backtrace
|
538
554
|
end
|
539
555
|
|
540
556
|
private
|
@@ -568,7 +584,7 @@ module ActiveSupport
|
|
568
584
|
end
|
569
585
|
|
570
586
|
def duration_of_variable_length?(obj)
|
571
|
-
ActiveSupport::Duration === obj && obj.
|
587
|
+
ActiveSupport::Duration === obj && obj.variable?
|
572
588
|
end
|
573
589
|
|
574
590
|
def wrap_with_time_zone(time)
|
@@ -583,3 +599,8 @@ module ActiveSupport
|
|
583
599
|
end
|
584
600
|
end
|
585
601
|
end
|
602
|
+
|
603
|
+
# These prevent Psych from calling `ActiveSupport::TimeWithZone.name`
|
604
|
+
# and triggering the deprecation warning about the change in Rails 7.1.
|
605
|
+
YAML.load_tags["!ruby/object:ActiveSupport::TimeWithZone"] = "ActiveSupport::TimeWithZone"
|
606
|
+
YAML.dump_tags[ActiveSupport::TimeWithZone] = "!ruby/object:ActiveSupport::TimeWithZone"
|
@@ -4,16 +4,16 @@ require "tzinfo"
|
|
4
4
|
require "concurrent/map"
|
5
5
|
|
6
6
|
module ActiveSupport
|
7
|
-
# The TimeZone class serves as a wrapper around TZInfo::Timezone instances.
|
7
|
+
# The TimeZone class serves as a wrapper around <tt>TZInfo::Timezone</tt> instances.
|
8
8
|
# It allows us to do the following:
|
9
9
|
#
|
10
10
|
# * Limit the set of zones provided by TZInfo to a meaningful subset of 134
|
11
11
|
# zones.
|
12
12
|
# * Retrieve and display zones with a friendlier name
|
13
13
|
# (e.g., "Eastern Time (US & Canada)" instead of "America/New_York").
|
14
|
-
# * Lazily load TZInfo::Timezone instances only when they're needed.
|
14
|
+
# * Lazily load <tt>TZInfo::Timezone</tt> instances only when they're needed.
|
15
15
|
# * Create ActiveSupport::TimeWithZone instances via TimeZone's +local+,
|
16
|
-
# +parse+, +at
|
16
|
+
# +parse+, +at+, and +now+ methods.
|
17
17
|
#
|
18
18
|
# If you set <tt>config.time_zone</tt> in the Rails Application, you can
|
19
19
|
# access this TimeZone object via <tt>Time.zone</tt>:
|
@@ -229,12 +229,16 @@ module ActiveSupport
|
|
229
229
|
# Returns +nil+ if no such time zone is known to the system.
|
230
230
|
def [](arg)
|
231
231
|
case arg
|
232
|
+
when self
|
233
|
+
arg
|
232
234
|
when String
|
233
235
|
begin
|
234
236
|
@lazy_zones_map[arg] ||= create(arg)
|
235
237
|
rescue TZInfo::InvalidTimezoneIdentifier
|
236
238
|
nil
|
237
239
|
end
|
240
|
+
when TZInfo::Timezone
|
241
|
+
@lazy_zones_map[arg.name] ||= create(arg.name, nil, arg)
|
238
242
|
when Numeric, ActiveSupport::Duration
|
239
243
|
arg *= 3600 if arg.abs <= 13
|
240
244
|
all.find { |z| z.utc_offset == arg.to_i }
|
@@ -256,7 +260,7 @@ module ActiveSupport
|
|
256
260
|
@country_zones[code] ||= load_country_zones(code)
|
257
261
|
end
|
258
262
|
|
259
|
-
def clear
|
263
|
+
def clear # :nodoc:
|
260
264
|
@lazy_zones_map = Concurrent::Map.new
|
261
265
|
@country_zones = Concurrent::Map.new
|
262
266
|
@zones = nil
|
@@ -381,14 +385,28 @@ module ActiveSupport
|
|
381
385
|
# If the string is invalid then an +ArgumentError+ will be raised unlike +parse+
|
382
386
|
# which usually returns +nil+ when given an invalid date string.
|
383
387
|
def iso8601(str)
|
388
|
+
# Historically `Date._iso8601(nil)` returns `{}`, but in the `date` gem versions `3.2.1`, `3.1.2`, `3.0.2`,
|
389
|
+
# and `2.0.1`, `Date._iso8601(nil)` raises `TypeError` https://github.com/ruby/date/issues/39
|
390
|
+
# Future `date` releases are expected to revert back to the original behavior.
|
391
|
+
raise ArgumentError, "invalid date" if str.nil?
|
392
|
+
|
384
393
|
parts = Date._iso8601(str)
|
385
394
|
|
386
|
-
|
395
|
+
year = parts.fetch(:year)
|
396
|
+
|
397
|
+
if parts.key?(:yday)
|
398
|
+
ordinal_date = Date.ordinal(year, parts.fetch(:yday))
|
399
|
+
month = ordinal_date.month
|
400
|
+
day = ordinal_date.day
|
401
|
+
else
|
402
|
+
month = parts.fetch(:mon)
|
403
|
+
day = parts.fetch(:mday)
|
404
|
+
end
|
387
405
|
|
388
406
|
time = Time.new(
|
389
|
-
|
390
|
-
|
391
|
-
|
407
|
+
year,
|
408
|
+
month,
|
409
|
+
day,
|
392
410
|
parts.fetch(:hour, 0),
|
393
411
|
parts.fetch(:min, 0),
|
394
412
|
parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0),
|
@@ -400,6 +418,9 @@ module ActiveSupport
|
|
400
418
|
else
|
401
419
|
TimeWithZone.new(nil, self, time)
|
402
420
|
end
|
421
|
+
|
422
|
+
rescue Date::Error, KeyError
|
423
|
+
raise ArgumentError, "invalid date"
|
403
424
|
end
|
404
425
|
|
405
426
|
# Method for creating new ActiveSupport::TimeWithZone instance in time zone
|
@@ -512,7 +533,7 @@ module ActiveSupport
|
|
512
533
|
def utc_to_local(time)
|
513
534
|
tzinfo.utc_to_local(time).yield_self do |t|
|
514
535
|
ActiveSupport.utc_to_local_returns_utc_offset_times ?
|
515
|
-
t : Time.utc(t.year, t.month, t.day, t.hour, t.min, t.sec, t.sec_fraction)
|
536
|
+
t : Time.utc(t.year, t.month, t.day, t.hour, t.min, t.sec, t.sec_fraction * 1_000_000)
|
516
537
|
end
|
517
538
|
end
|
518
539
|
|
@@ -522,27 +543,27 @@ module ActiveSupport
|
|
522
543
|
tzinfo.local_to_utc(time, dst)
|
523
544
|
end
|
524
545
|
|
525
|
-
# Available so that TimeZone instances respond like TZInfo::Timezone
|
546
|
+
# Available so that TimeZone instances respond like <tt>TZInfo::Timezone</tt>
|
526
547
|
# instances.
|
527
548
|
def period_for_utc(time)
|
528
549
|
tzinfo.period_for_utc(time)
|
529
550
|
end
|
530
551
|
|
531
|
-
# Available so that TimeZone instances respond like TZInfo::Timezone
|
552
|
+
# Available so that TimeZone instances respond like <tt>TZInfo::Timezone</tt>
|
532
553
|
# instances.
|
533
554
|
def period_for_local(time, dst = true)
|
534
555
|
tzinfo.period_for_local(time, dst) { |periods| periods.last }
|
535
556
|
end
|
536
557
|
|
537
|
-
def periods_for_local(time)
|
558
|
+
def periods_for_local(time) # :nodoc:
|
538
559
|
tzinfo.periods_for_local(time)
|
539
560
|
end
|
540
561
|
|
541
|
-
def init_with(coder)
|
562
|
+
def init_with(coder) # :nodoc:
|
542
563
|
initialize(coder["name"])
|
543
564
|
end
|
544
565
|
|
545
|
-
def encode_with(coder)
|
566
|
+
def encode_with(coder) # :nodoc:
|
546
567
|
coder.tag = "!ruby/object:#{self.class}"
|
547
568
|
coder.map = { "name" => tzinfo.name }
|
548
569
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require_relative "gem_version"
|
4
4
|
|
5
5
|
module ActiveSupport
|
6
|
-
# Returns the version of
|
6
|
+
# Returns the currently loaded version of Active Support as a <tt>Gem::Version</tt>.
|
7
7
|
def self.version
|
8
8
|
gem_version
|
9
9
|
end
|
@@ -5,7 +5,7 @@ require "active_support/core_ext/object/blank"
|
|
5
5
|
require "stringio"
|
6
6
|
|
7
7
|
module ActiveSupport
|
8
|
-
module XmlMini_LibXML
|
8
|
+
module XmlMini_LibXML # :nodoc:
|
9
9
|
extend self
|
10
10
|
|
11
11
|
# Parse an XML Document string or IO into a simple hash using libxml.
|
@@ -25,15 +25,15 @@ module ActiveSupport
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
module LibXML
|
29
|
-
module Conversions
|
30
|
-
module Document
|
28
|
+
module LibXML # :nodoc:
|
29
|
+
module Conversions # :nodoc:
|
30
|
+
module Document # :nodoc:
|
31
31
|
def to_hash
|
32
32
|
root.to_hash
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
module Node
|
36
|
+
module Node # :nodoc:
|
37
37
|
CONTENT_ROOT = "__content__"
|
38
38
|
|
39
39
|
# Convert XML document to hash.
|