activesupport 4.2.11.1 → 5.2.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +399 -440
- data/MIT-LICENSE +2 -2
- data/README.rdoc +4 -5
- data/lib/active_support/all.rb +5 -3
- data/lib/active_support/array_inquirer.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +7 -5
- data/lib/active_support/benchmarkable.rb +6 -4
- data/lib/active_support/builder.rb +3 -1
- data/lib/active_support/cache/file_store.rb +41 -35
- data/lib/active_support/cache/mem_cache_store.rb +97 -88
- data/lib/active_support/cache/memory_store.rb +27 -30
- data/lib/active_support/cache/null_store.rb +7 -8
- data/lib/active_support/cache/redis_cache_store.rb +461 -0
- data/lib/active_support/cache/strategy/local_cache.rb +67 -34
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
- data/lib/active_support/cache.rb +287 -196
- data/lib/active_support/callbacks.rb +640 -590
- data/lib/active_support/concern.rb +11 -5
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +17 -0
- data/lib/active_support/concurrency/share_lock.rb +227 -0
- data/lib/active_support/configurable.rb +8 -5
- data/lib/active_support/core_ext/array/access.rb +29 -1
- data/lib/active_support/core_ext/array/conversions.rb +22 -18
- data/lib/active_support/core_ext/array/extract_options.rb +2 -0
- data/lib/active_support/core_ext/array/grouping.rb +11 -18
- data/lib/active_support/core_ext/array/inquiry.rb +19 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +5 -3
- data/lib/active_support/core_ext/array/wrap.rb +7 -4
- data/lib/active_support/core_ext/array.rb +9 -6
- data/lib/active_support/core_ext/benchmark.rb +3 -1
- data/lib/active_support/core_ext/big_decimal/conversions.rb +10 -12
- data/lib/active_support/core_ext/big_decimal.rb +3 -1
- data/lib/active_support/core_ext/class/attribute.rb +41 -22
- data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
- data/lib/active_support/core_ext/class/subclasses.rb +20 -6
- data/lib/active_support/core_ext/class.rb +4 -3
- data/lib/active_support/core_ext/date/acts_like.rb +3 -1
- data/lib/active_support/core_ext/date/blank.rb +14 -0
- data/lib/active_support/core_ext/date/calculations.rb +11 -9
- data/lib/active_support/core_ext/date/conversions.rb +25 -23
- data/lib/active_support/core_ext/date/zones.rb +4 -2
- data/lib/active_support/core_ext/date.rb +6 -4
- data/lib/active_support/core_ext/date_and_time/calculations.rb +170 -58
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +4 -3
- data/lib/active_support/core_ext/date_and_time/zones.rb +12 -12
- data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
- data/lib/active_support/core_ext/date_time/blank.rb +14 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +36 -18
- data/lib/active_support/core_ext/date_time/compatibility.rb +8 -6
- data/lib/active_support/core_ext/date_time/conversions.rb +16 -12
- data/lib/active_support/core_ext/date_time.rb +7 -5
- data/lib/active_support/core_ext/digest/uuid.rb +7 -5
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +101 -33
- data/lib/active_support/core_ext/file/atomic.rb +38 -31
- data/lib/active_support/core_ext/file.rb +3 -1
- data/lib/active_support/core_ext/hash/compact.rb +14 -9
- data/lib/active_support/core_ext/hash/conversions.rb +62 -41
- data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
- data/lib/active_support/core_ext/hash/except.rb +11 -8
- data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
- data/lib/active_support/core_ext/hash/keys.rb +33 -27
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +8 -8
- data/lib/active_support/core_ext/hash/transform_values.rb +14 -5
- data/lib/active_support/core_ext/hash.rb +11 -9
- data/lib/active_support/core_ext/integer/inflections.rb +3 -1
- data/lib/active_support/core_ext/integer/multiple.rb +2 -0
- data/lib/active_support/core_ext/integer/time.rb +11 -18
- data/lib/active_support/core_ext/integer.rb +5 -3
- data/lib/active_support/core_ext/kernel/agnostics.rb +2 -0
- data/lib/active_support/core_ext/kernel/concern.rb +5 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -84
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/kernel.rb +6 -5
- data/lib/active_support/core_ext/load_error.rb +3 -22
- data/lib/active_support/core_ext/marshal.rb +8 -8
- data/lib/active_support/core_ext/module/aliasing.rb +6 -44
- data/lib/active_support/core_ext/module/anonymous.rb +12 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +8 -9
- data/lib/active_support/core_ext/module/attribute_accessors.rb +43 -40
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +150 -0
- data/lib/active_support/core_ext/module/concerning.rb +11 -12
- data/lib/active_support/core_ext/module/delegation.rb +99 -29
- data/lib/active_support/core_ext/module/deprecation.rb +4 -2
- data/lib/active_support/core_ext/module/introspection.rb +9 -9
- data/lib/active_support/core_ext/module/reachable.rb +5 -2
- data/lib/active_support/core_ext/module/redefine_method.rb +49 -0
- data/lib/active_support/core_ext/module/remove_method.rb +8 -3
- data/lib/active_support/core_ext/module.rb +14 -11
- data/lib/active_support/core_ext/name_error.rb +22 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +78 -81
- data/lib/active_support/core_ext/numeric/inquiry.rb +28 -0
- data/lib/active_support/core_ext/numeric/time.rb +35 -23
- data/lib/active_support/core_ext/numeric.rb +6 -3
- data/lib/active_support/core_ext/object/acts_like.rb +12 -1
- data/lib/active_support/core_ext/object/blank.rb +27 -2
- data/lib/active_support/core_ext/object/conversions.rb +6 -4
- data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
- data/lib/active_support/core_ext/object/duplicable.rb +41 -14
- data/lib/active_support/core_ext/object/inclusion.rb +5 -3
- data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
- data/lib/active_support/core_ext/object/json.rb +49 -19
- data/lib/active_support/core_ext/object/to_param.rb +3 -1
- data/lib/active_support/core_ext/object/to_query.rb +10 -5
- data/lib/active_support/core_ext/object/try.rb +69 -21
- data/lib/active_support/core_ext/object/with_options.rb +16 -3
- data/lib/active_support/core_ext/object.rb +14 -13
- data/lib/active_support/core_ext/range/compare_range.rb +61 -0
- data/lib/active_support/core_ext/range/conversions.rb +27 -7
- data/lib/active_support/core_ext/range/each.rb +19 -17
- data/lib/active_support/core_ext/range/include_range.rb +2 -22
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
- data/lib/active_support/core_ext/range/overlaps.rb +2 -0
- data/lib/active_support/core_ext/range.rb +7 -4
- data/lib/active_support/core_ext/regexp.rb +6 -0
- data/lib/active_support/core_ext/securerandom.rb +25 -0
- data/lib/active_support/core_ext/string/access.rb +8 -6
- data/lib/active_support/core_ext/string/behavior.rb +3 -1
- data/lib/active_support/core_ext/string/conversions.rb +7 -4
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +6 -5
- data/lib/active_support/core_ext/string/indent.rb +6 -4
- data/lib/active_support/core_ext/string/inflections.rb +61 -24
- data/lib/active_support/core_ext/string/inquiry.rb +3 -1
- data/lib/active_support/core_ext/string/multibyte.rb +15 -7
- data/lib/active_support/core_ext/string/output_safety.rb +34 -38
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
- data/lib/active_support/core_ext/string/strip.rb +4 -5
- data/lib/active_support/core_ext/string/zones.rb +4 -2
- data/lib/active_support/core_ext/string.rb +15 -13
- data/lib/active_support/core_ext/time/acts_like.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +85 -51
- data/lib/active_support/core_ext/time/compatibility.rb +4 -2
- data/lib/active_support/core_ext/time/conversions.rb +20 -13
- data/lib/active_support/core_ext/time/zones.rb +41 -7
- data/lib/active_support/core_ext/time.rb +7 -6
- data/lib/active_support/core_ext/uri.rb +6 -8
- data/lib/active_support/core_ext.rb +3 -1
- data/lib/active_support/current_attributes.rb +195 -0
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +57 -0
- data/lib/active_support/dependencies.rb +152 -161
- data/lib/active_support/deprecation/behaviors.rb +44 -11
- data/lib/active_support/deprecation/constant_accessor.rb +52 -0
- data/lib/active_support/deprecation/instance_delegator.rb +17 -2
- data/lib/active_support/deprecation/method_wrappers.rb +66 -20
- data/lib/active_support/deprecation/proxy_wrappers.rb +56 -28
- data/lib/active_support/deprecation/reporting.rb +32 -12
- data/lib/active_support/deprecation.rb +12 -9
- data/lib/active_support/descendants_tracker.rb +2 -0
- data/lib/active_support/digest.rb +20 -0
- data/lib/active_support/duration/iso8601_parser.rb +125 -0
- data/lib/active_support/duration/iso8601_serializer.rb +55 -0
- data/lib/active_support/duration.rb +307 -35
- data/lib/active_support/encrypted_configuration.rb +49 -0
- data/lib/active_support/encrypted_file.rb +99 -0
- data/lib/active_support/evented_file_update_checker.rb +205 -0
- data/lib/active_support/execution_wrapper.rb +128 -0
- data/lib/active_support/executor.rb +8 -0
- data/lib/active_support/file_update_checker.rb +63 -37
- data/lib/active_support/gem_version.rb +6 -4
- data/lib/active_support/gzip.rb +7 -5
- data/lib/active_support/hash_with_indifferent_access.rb +123 -28
- data/lib/active_support/i18n.rb +8 -6
- data/lib/active_support/i18n_railtie.rb +37 -13
- data/lib/active_support/inflections.rb +13 -11
- data/lib/active_support/inflector/inflections.rb +61 -12
- data/lib/active_support/inflector/methods.rb +163 -136
- data/lib/active_support/inflector/transliterate.rb +48 -27
- data/lib/active_support/inflector.rb +7 -5
- data/lib/active_support/json/decoding.rb +16 -13
- data/lib/active_support/json/encoding.rb +11 -58
- data/lib/active_support/json.rb +4 -2
- data/lib/active_support/key_generator.rb +25 -25
- data/lib/active_support/lazy_load_hooks.rb +50 -20
- data/lib/active_support/locale/en.yml +2 -0
- data/lib/active_support/log_subscriber/test_helper.rb +14 -12
- data/lib/active_support/log_subscriber.rb +13 -10
- data/lib/active_support/logger.rb +8 -7
- data/lib/active_support/logger_silence.rb +6 -4
- data/lib/active_support/logger_thread_safe_level.rb +7 -5
- data/lib/active_support/message_encryptor.rb +168 -53
- data/lib/active_support/message_verifier.rb +150 -17
- data/lib/active_support/messages/metadata.rb +71 -0
- data/lib/active_support/messages/rotation_configuration.rb +22 -0
- data/lib/active_support/messages/rotator.rb +56 -0
- data/lib/active_support/multibyte/chars.rb +36 -23
- data/lib/active_support/multibyte/unicode.rb +100 -96
- data/lib/active_support/multibyte.rb +4 -2
- data/lib/active_support/notifications/fanout.rb +11 -9
- data/lib/active_support/notifications/instrumenter.rb +27 -7
- data/lib/active_support/notifications.rb +11 -7
- data/lib/active_support/number_helper/number_converter.rb +13 -11
- data/lib/active_support/number_helper/number_to_currency_converter.rb +9 -9
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +9 -3
- data/lib/active_support/number_helper/number_to_human_converter.rb +11 -9
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +9 -8
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +13 -4
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +23 -56
- data/lib/active_support/number_helper/rounding_helper.rb +66 -0
- data/lib/active_support/number_helper.rb +94 -68
- data/lib/active_support/option_merger.rb +3 -1
- data/lib/active_support/ordered_hash.rb +6 -4
- data/lib/active_support/ordered_options.rb +23 -5
- data/lib/active_support/per_thread_registry.rb +9 -4
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +16 -8
- data/lib/active_support/railtie.rb +43 -9
- data/lib/active_support/reloader.rb +131 -0
- data/lib/active_support/rescuable.rb +108 -53
- data/lib/active_support/security_utils.rb +15 -11
- data/lib/active_support/string_inquirer.rb +11 -3
- data/lib/active_support/subscriber.rb +21 -16
- data/lib/active_support/tagged_logging.rb +14 -11
- data/lib/active_support/test_case.rb +19 -47
- data/lib/active_support/testing/assertions.rb +137 -20
- data/lib/active_support/testing/autorun.rb +4 -2
- data/lib/active_support/testing/constant_lookup.rb +2 -1
- data/lib/active_support/testing/declarative.rb +3 -1
- data/lib/active_support/testing/deprecation.rb +14 -10
- data/lib/active_support/testing/file_fixtures.rb +36 -0
- data/lib/active_support/testing/isolation.rb +34 -25
- data/lib/active_support/testing/method_call_assertions.rb +43 -0
- data/lib/active_support/testing/setup_and_teardown.rb +13 -8
- data/lib/active_support/testing/stream.rb +44 -0
- data/lib/active_support/testing/tagged_logging.rb +3 -1
- data/lib/active_support/testing/time_helpers.rb +81 -15
- data/lib/active_support/time.rb +14 -12
- data/lib/active_support/time_with_zone.rb +169 -39
- data/lib/active_support/values/time_zone.rb +196 -61
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +3 -1
- data/lib/active_support/xml_mini/jdom.rb +116 -114
- data/lib/active_support/xml_mini/libxml.rb +16 -13
- data/lib/active_support/xml_mini/libxmlsax.rb +15 -14
- data/lib/active_support/xml_mini/nokogiri.rb +14 -12
- data/lib/active_support/xml_mini/nokogirisax.rb +14 -13
- data/lib/active_support/xml_mini/rexml.rb +11 -9
- data/lib/active_support/xml_mini.rb +37 -37
- data/lib/active_support.rb +12 -11
- metadata +54 -24
- data/lib/active_support/concurrency/latch.rb +0 -27
- data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
- data/lib/active_support/core_ext/date_time/zones.rb +0 -6
- data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
- data/lib/active_support/core_ext/module/method_transplanting.rb +0 -13
- data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
- data/lib/active_support/core_ext/object/itself.rb +0 -15
- data/lib/active_support/core_ext/struct.rb +0 -6
- data/lib/active_support/core_ext/thread.rb +0 -86
- data/lib/active_support/core_ext/time/marshal.rb +0 -30
@@ -1,48 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/module/redefine_method"
|
4
|
+
require "active_support/core_ext/string/strip" # for strip_heredoc
|
5
|
+
require "active_support/core_ext/time/calculations"
|
6
|
+
require "concurrent/map"
|
7
|
+
|
1
8
|
module ActiveSupport
|
2
9
|
module Testing
|
3
10
|
class SimpleStubs # :nodoc:
|
4
11
|
Stub = Struct.new(:object, :method_name, :original_method)
|
5
12
|
|
6
13
|
def initialize
|
7
|
-
@stubs = {}
|
14
|
+
@stubs = Concurrent::Map.new { |h, k| h[k] = {} }
|
8
15
|
end
|
9
16
|
|
10
17
|
def stub_object(object, method_name, &block)
|
11
|
-
|
12
|
-
|
13
|
-
if stub = @stubs[key]
|
18
|
+
if stub = stubbing(object, method_name)
|
14
19
|
unstub_object(stub)
|
15
20
|
end
|
16
21
|
|
17
22
|
new_name = "__simple_stub__#{method_name}"
|
18
23
|
|
19
|
-
@stubs[
|
24
|
+
@stubs[object.object_id][method_name] = Stub.new(object, method_name, new_name)
|
20
25
|
|
21
26
|
object.singleton_class.send :alias_method, new_name, method_name
|
22
27
|
object.define_singleton_method(method_name, &block)
|
23
28
|
end
|
24
29
|
|
25
30
|
def unstub_all!
|
26
|
-
@stubs.each_value do |
|
27
|
-
|
31
|
+
@stubs.each_value do |object_stubs|
|
32
|
+
object_stubs.each_value do |stub|
|
33
|
+
unstub_object(stub)
|
34
|
+
end
|
28
35
|
end
|
29
|
-
@stubs
|
36
|
+
@stubs.clear
|
37
|
+
end
|
38
|
+
|
39
|
+
def stubbing(object, method_name)
|
40
|
+
@stubs[object.object_id][method_name]
|
30
41
|
end
|
31
42
|
|
32
43
|
private
|
33
44
|
|
34
45
|
def unstub_object(stub)
|
35
46
|
singleton_class = stub.object.singleton_class
|
36
|
-
singleton_class.send :
|
47
|
+
singleton_class.send :silence_redefinition_of_method, stub.method_name
|
37
48
|
singleton_class.send :alias_method, stub.method_name, stub.original_method
|
38
49
|
singleton_class.send :undef_method, stub.original_method
|
39
50
|
end
|
40
51
|
end
|
41
52
|
|
42
|
-
#
|
53
|
+
# Contains helpers that help you test passage of time.
|
43
54
|
module TimeHelpers
|
55
|
+
def after_teardown
|
56
|
+
travel_back
|
57
|
+
super
|
58
|
+
end
|
59
|
+
|
44
60
|
# Changes current time to the time in the future or in the past by a given time difference by
|
45
|
-
# stubbing +Time.now+, +Date.today+, and +DateTime.now+.
|
61
|
+
# stubbing +Time.now+, +Date.today+, and +DateTime.now+. The stubs are automatically removed
|
62
|
+
# at the end of the test.
|
46
63
|
#
|
47
64
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
48
65
|
# travel 1.day
|
@@ -64,9 +81,10 @@ module ActiveSupport
|
|
64
81
|
|
65
82
|
# Changes current time to the given time by stubbing +Time.now+,
|
66
83
|
# +Date.today+, and +DateTime.now+ to return the time or date passed into this method.
|
84
|
+
# The stubs are automatically removed at the end of the test.
|
67
85
|
#
|
68
86
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
69
|
-
# travel_to Time.
|
87
|
+
# travel_to Time.zone.local(2004, 11, 24, 01, 04, 44)
|
70
88
|
# Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
|
71
89
|
# Date.current # => Wed, 24 Nov 2004
|
72
90
|
# DateTime.current # => Wed, 24 Nov 2004 01:04:44 -0500
|
@@ -88,11 +106,39 @@ module ActiveSupport
|
|
88
106
|
# state at the end of the block:
|
89
107
|
#
|
90
108
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
91
|
-
# travel_to Time.
|
109
|
+
# travel_to Time.zone.local(2004, 11, 24, 01, 04, 44) do
|
92
110
|
# Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
|
93
111
|
# end
|
94
112
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
95
113
|
def travel_to(date_or_time)
|
114
|
+
if block_given? && simple_stubs.stubbing(Time, :now)
|
115
|
+
travel_to_nested_block_call = <<-MSG.strip_heredoc
|
116
|
+
|
117
|
+
Calling `travel_to` with a block, when we have previously already made a call to `travel_to`, can lead to confusing time stubbing.
|
118
|
+
|
119
|
+
Instead of:
|
120
|
+
|
121
|
+
travel_to 2.days.from_now do
|
122
|
+
# 2 days from today
|
123
|
+
travel_to 3.days.from_now do
|
124
|
+
# 5 days from today
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
preferred way to achieve above is:
|
129
|
+
|
130
|
+
travel 2.days do
|
131
|
+
# 2 days from today
|
132
|
+
end
|
133
|
+
|
134
|
+
travel 5.days do
|
135
|
+
# 5 days from today
|
136
|
+
end
|
137
|
+
|
138
|
+
MSG
|
139
|
+
raise travel_to_nested_block_call
|
140
|
+
end
|
141
|
+
|
96
142
|
if date_or_time.is_a?(Date) && !date_or_time.is_a?(DateTime)
|
97
143
|
now = date_or_time.midnight.to_time
|
98
144
|
else
|
@@ -113,10 +159,10 @@ module ActiveSupport
|
|
113
159
|
end
|
114
160
|
|
115
161
|
# Returns the current time back to its original state, by removing the stubs added by
|
116
|
-
#
|
162
|
+
# +travel+ and +travel_to+.
|
117
163
|
#
|
118
164
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
119
|
-
# travel_to Time.
|
165
|
+
# travel_to Time.zone.local(2004, 11, 24, 01, 04, 44)
|
120
166
|
# Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
|
121
167
|
# travel_back
|
122
168
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
@@ -124,6 +170,26 @@ module ActiveSupport
|
|
124
170
|
simple_stubs.unstub_all!
|
125
171
|
end
|
126
172
|
|
173
|
+
# Calls +travel_to+ with +Time.now+.
|
174
|
+
#
|
175
|
+
# Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00
|
176
|
+
# freeze_time
|
177
|
+
# sleep(1)
|
178
|
+
# Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00
|
179
|
+
#
|
180
|
+
# This method also accepts a block, which will return the current time back to its original
|
181
|
+
# state at the end of the block:
|
182
|
+
#
|
183
|
+
# Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00
|
184
|
+
# freeze_time do
|
185
|
+
# sleep(1)
|
186
|
+
# User.create.created_at # => Sun, 09 Jul 2017 15:34:49 EST -05:00
|
187
|
+
# end
|
188
|
+
# Time.current # => Sun, 09 Jul 2017 15:34:50 EST -05:00
|
189
|
+
def freeze_time(&block)
|
190
|
+
travel_to Time.now, &block
|
191
|
+
end
|
192
|
+
|
127
193
|
private
|
128
194
|
|
129
195
|
def simple_stubs
|
data/lib/active_support/time.rb
CHANGED
@@ -1,18 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveSupport
|
2
|
-
autoload :Duration,
|
3
|
-
autoload :TimeWithZone,
|
4
|
-
autoload :TimeZone,
|
4
|
+
autoload :Duration, "active_support/duration"
|
5
|
+
autoload :TimeWithZone, "active_support/time_with_zone"
|
6
|
+
autoload :TimeZone, "active_support/values/time_zone"
|
5
7
|
end
|
6
8
|
|
7
|
-
require
|
8
|
-
require
|
9
|
+
require "date"
|
10
|
+
require "time"
|
9
11
|
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
12
|
+
require "active_support/core_ext/time"
|
13
|
+
require "active_support/core_ext/date"
|
14
|
+
require "active_support/core_ext/date_time"
|
13
15
|
|
14
|
-
require
|
15
|
-
require
|
16
|
+
require "active_support/core_ext/integer/time"
|
17
|
+
require "active_support/core_ext/numeric/time"
|
16
18
|
|
17
|
-
require
|
18
|
-
require
|
19
|
+
require "active_support/core_ext/string/conversions"
|
20
|
+
require "active_support/core_ext/string/zones"
|
@@ -1,6 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/duration"
|
4
|
+
require "active_support/values/time_zone"
|
5
|
+
require "active_support/core_ext/object/acts_like"
|
6
|
+
require "active_support/core_ext/date_and_time/compatibility"
|
4
7
|
|
5
8
|
module ActiveSupport
|
6
9
|
# A Time-like class that can represent a time in any time zone. Necessary
|
@@ -14,7 +17,7 @@ module ActiveSupport
|
|
14
17
|
# Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
|
15
18
|
# Time.zone.local(2007, 2, 10, 15, 30, 45) # => Sat, 10 Feb 2007 15:30:45 EST -05:00
|
16
19
|
# Time.zone.parse('2007-02-10 15:30:45') # => Sat, 10 Feb 2007 15:30:45 EST -05:00
|
17
|
-
# Time.zone.at(
|
20
|
+
# Time.zone.at(1171139445) # => Sat, 10 Feb 2007 15:30:45 EST -05:00
|
18
21
|
# Time.zone.now # => Sun, 18 May 2008 13:07:55 EDT -04:00
|
19
22
|
# Time.utc(2007, 2, 10, 20, 30, 45).in_time_zone # => Sat, 10 Feb 2007 15:30:45 EST -05:00
|
20
23
|
#
|
@@ -35,12 +38,14 @@ module ActiveSupport
|
|
35
38
|
# t.is_a?(Time) # => true
|
36
39
|
# t.is_a?(ActiveSupport::TimeWithZone) # => true
|
37
40
|
class TimeWithZone
|
38
|
-
|
39
41
|
# Report class name as 'Time' to thwart type checking.
|
40
42
|
def self.name
|
41
|
-
|
43
|
+
"Time"
|
42
44
|
end
|
43
45
|
|
46
|
+
PRECISIONS = Hash.new { |h, n| h[n] = "%FT%T.%#{n}N".freeze }
|
47
|
+
PRECISIONS[0] = "%FT%T".freeze
|
48
|
+
|
44
49
|
include Comparable, DateAndTime::Compatibility
|
45
50
|
attr_reader :time_zone
|
46
51
|
|
@@ -99,7 +104,7 @@ module ActiveSupport
|
|
99
104
|
# Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
|
100
105
|
# Time.zone.now.utc? # => false
|
101
106
|
def utc?
|
102
|
-
|
107
|
+
period.offset.abbreviation == :UTC || period.offset.abbreviation == :UCT
|
103
108
|
end
|
104
109
|
alias_method :gmt?, :utc?
|
105
110
|
|
@@ -122,24 +127,30 @@ module ActiveSupport
|
|
122
127
|
utc? && alternate_utc_string || TimeZone.seconds_to_utc_offset(utc_offset, colon)
|
123
128
|
end
|
124
129
|
|
125
|
-
#
|
126
|
-
#
|
130
|
+
# Returns the time zone abbreviation.
|
131
|
+
#
|
132
|
+
# Time.zone = 'Eastern Time (US & Canada)' # => "Eastern Time (US & Canada)"
|
133
|
+
# Time.zone.now.zone # => "EST"
|
127
134
|
def zone
|
128
135
|
period.zone_identifier.to_s
|
129
136
|
end
|
130
137
|
|
138
|
+
# Returns a string of the object's date, time, zone, and offset from UTC.
|
139
|
+
#
|
140
|
+
# Time.zone.now.inspect # => "Thu, 04 Dec 2014 11:00:25 EST -05:00"
|
131
141
|
def inspect
|
132
142
|
"#{time.strftime('%a, %d %b %Y %H:%M:%S')} #{zone} #{formatted_offset}"
|
133
143
|
end
|
134
144
|
|
145
|
+
# Returns a string of the object's date and time in the ISO 8601 standard
|
146
|
+
# format.
|
147
|
+
#
|
148
|
+
# Time.zone.now.xmlschema # => "2014-12-04T11:02:37-05:00"
|
135
149
|
def xmlschema(fraction_digits = 0)
|
136
|
-
|
137
|
-
(".%06i" % time.usec)[0, fraction_digits.to_i + 1]
|
138
|
-
end
|
139
|
-
|
140
|
-
"#{time.strftime("%Y-%m-%dT%H:%M:%S")}#{fraction}#{formatted_offset(true, 'Z')}"
|
150
|
+
"#{time.strftime(PRECISIONS[fraction_digits.to_i])}#{formatted_offset(true, 'Z'.freeze)}"
|
141
151
|
end
|
142
152
|
alias_method :iso8601, :xmlschema
|
153
|
+
alias_method :rfc3339, :xmlschema
|
143
154
|
|
144
155
|
# Coerces time to a string for JSON encoding. The default format is ISO 8601.
|
145
156
|
# You can get %Y/%m/%d %H:%M:%S +offset style by setting
|
@@ -162,15 +173,12 @@ module ActiveSupport
|
|
162
173
|
end
|
163
174
|
|
164
175
|
def init_with(coder) #:nodoc:
|
165
|
-
initialize(coder[
|
176
|
+
initialize(coder["utc"], coder["zone"], coder["time"])
|
166
177
|
end
|
167
178
|
|
168
179
|
def encode_with(coder) #:nodoc:
|
169
|
-
|
170
|
-
|
171
|
-
else
|
172
|
-
coder.represent_scalar(nil, utc.strftime("%Y-%m-%d %H:%M:%S.%9NZ"))
|
173
|
-
end
|
180
|
+
coder.tag = "!ruby/object:ActiveSupport::TimeWithZone"
|
181
|
+
coder.map = { "utc" => utc, "zone" => time_zone, "time" => time }
|
174
182
|
end
|
175
183
|
|
176
184
|
# Returns a string of the object's date and time in the format used by
|
@@ -192,7 +200,7 @@ module ActiveSupport
|
|
192
200
|
|
193
201
|
# Returns a string of the object's date and time.
|
194
202
|
# Accepts an optional <tt>format</tt>:
|
195
|
-
# * <tt>:default</tt> - default value, mimics Ruby
|
203
|
+
# * <tt>:default</tt> - default value, mimics Ruby Time#to_s format.
|
196
204
|
# * <tt>:db</tt> - format outputs time in UTC :db time. See Time#to_formatted_s(:db).
|
197
205
|
# * Any key in <tt>Time::DATE_FORMATS</tt> can be used. See active_support/core_ext/time/conversions.rb.
|
198
206
|
def to_s(format = :default)
|
@@ -201,7 +209,7 @@ module ActiveSupport
|
|
201
209
|
elsif formatter = ::Time::DATE_FORMATS[format]
|
202
210
|
formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
|
203
211
|
else
|
204
|
-
"#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}" # mimicking Ruby
|
212
|
+
"#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}" # mimicking Ruby Time#to_s format
|
205
213
|
end
|
206
214
|
end
|
207
215
|
alias_method :to_formatted_s, :to_s
|
@@ -240,6 +248,7 @@ module ActiveSupport
|
|
240
248
|
utc.future?
|
241
249
|
end
|
242
250
|
|
251
|
+
# Returns +true+ if +other+ is equal to current object.
|
243
252
|
def eql?(other)
|
244
253
|
other.eql?(utc)
|
245
254
|
end
|
@@ -248,9 +257,23 @@ module ActiveSupport
|
|
248
257
|
utc.hash
|
249
258
|
end
|
250
259
|
|
260
|
+
# Adds an interval of time to the current object's time and returns that
|
261
|
+
# value as a new TimeWithZone object.
|
262
|
+
#
|
263
|
+
# Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
|
264
|
+
# now = Time.zone.now # => Sun, 02 Nov 2014 01:26:28 EDT -04:00
|
265
|
+
# now + 1000 # => Sun, 02 Nov 2014 01:43:08 EDT -04:00
|
266
|
+
#
|
267
|
+
# If we're adding a Duration of variable length (i.e., years, months, days),
|
268
|
+
# move forward from #time, otherwise move forward from #utc, for accuracy
|
269
|
+
# when moving across DST boundaries.
|
270
|
+
#
|
271
|
+
# For instance, a time + 24.hours will advance exactly 24 hours, while a
|
272
|
+
# time + 1.day will advance 23-25 hours, depending on the day.
|
273
|
+
#
|
274
|
+
# now + 24.hours # => Mon, 03 Nov 2014 00:26:28 EST -05:00
|
275
|
+
# now + 1.day # => Mon, 03 Nov 2014 01:26:28 EST -05:00
|
251
276
|
def +(other)
|
252
|
-
# If we're adding a Duration of variable length (i.e., years, months, days), move forward from #time,
|
253
|
-
# otherwise move forward from #utc, for accuracy when moving across DST boundaries
|
254
277
|
if duration_of_variable_length?(other)
|
255
278
|
method_missing(:+, other)
|
256
279
|
else
|
@@ -258,10 +281,26 @@ module ActiveSupport
|
|
258
281
|
result.in_time_zone(time_zone)
|
259
282
|
end
|
260
283
|
end
|
284
|
+
alias_method :since, :+
|
285
|
+
alias_method :in, :+
|
261
286
|
|
287
|
+
# Returns a new TimeWithZone object that represents the difference between
|
288
|
+
# the current object's time and the +other+ time.
|
289
|
+
#
|
290
|
+
# Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
|
291
|
+
# now = Time.zone.now # => Mon, 03 Nov 2014 00:26:28 EST -05:00
|
292
|
+
# now - 1000 # => Mon, 03 Nov 2014 00:09:48 EST -05:00
|
293
|
+
#
|
294
|
+
# If subtracting a Duration of variable length (i.e., years, months, days),
|
295
|
+
# move backward from #time, otherwise move backward from #utc, for accuracy
|
296
|
+
# when moving across DST boundaries.
|
297
|
+
#
|
298
|
+
# For instance, a time - 24.hours will go subtract exactly 24 hours, while a
|
299
|
+
# time - 1.day will subtract 23-25 hours, depending on the day.
|
300
|
+
#
|
301
|
+
# now - 24.hours # => Sun, 02 Nov 2014 01:26:28 EDT -04:00
|
302
|
+
# now - 1.day # => Sun, 02 Nov 2014 00:26:28 EDT -04:00
|
262
303
|
def -(other)
|
263
|
-
# If we're subtracting a Duration of variable length (i.e., years, months, days), move backwards from #time,
|
264
|
-
# otherwise move backwards #utc, for accuracy when moving across DST boundaries
|
265
304
|
if other.acts_like?(:time)
|
266
305
|
to_time - other.to_time
|
267
306
|
elsif duration_of_variable_length?(other)
|
@@ -272,21 +311,84 @@ module ActiveSupport
|
|
272
311
|
end
|
273
312
|
end
|
274
313
|
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
314
|
+
# Subtracts an interval of time from the current object's time and returns
|
315
|
+
# the result as a new TimeWithZone object.
|
316
|
+
#
|
317
|
+
# Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
|
318
|
+
# now = Time.zone.now # => Mon, 03 Nov 2014 00:26:28 EST -05:00
|
319
|
+
# now.ago(1000) # => Mon, 03 Nov 2014 00:09:48 EST -05:00
|
320
|
+
#
|
321
|
+
# If we're subtracting a Duration of variable length (i.e., years, months,
|
322
|
+
# days), move backward from #time, otherwise move backward from #utc, for
|
323
|
+
# accuracy when moving across DST boundaries.
|
324
|
+
#
|
325
|
+
# For instance, <tt>time.ago(24.hours)</tt> will move back exactly 24 hours,
|
326
|
+
# while <tt>time.ago(1.day)</tt> will move back 23-25 hours, depending on
|
327
|
+
# the day.
|
328
|
+
#
|
329
|
+
# now.ago(24.hours) # => Sun, 02 Nov 2014 01:26:28 EDT -04:00
|
330
|
+
# now.ago(1.day) # => Sun, 02 Nov 2014 00:26:28 EDT -04:00
|
286
331
|
def ago(other)
|
287
332
|
since(-other)
|
288
333
|
end
|
289
334
|
|
335
|
+
# Returns a new +ActiveSupport::TimeWithZone+ where one or more of the elements have
|
336
|
+
# been changed according to the +options+ parameter. The time options (<tt>:hour</tt>,
|
337
|
+
# <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly,
|
338
|
+
# so if only the hour is passed, then minute, sec, usec and nsec is set to 0. If the
|
339
|
+
# hour and minute is passed, then sec, usec and nsec is set to 0. The +options+
|
340
|
+
# parameter takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>,
|
341
|
+
# <tt>:day</tt>, <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>,
|
342
|
+
# <tt>:nsec</tt>, <tt>:offset</tt>, <tt>:zone</tt>. Pass either <tt>:usec</tt>
|
343
|
+
# or <tt>:nsec</tt>, not both. Similarly, pass either <tt>:zone</tt> or
|
344
|
+
# <tt>:offset</tt>, not both.
|
345
|
+
#
|
346
|
+
# t = Time.zone.now # => Fri, 14 Apr 2017 11:45:15 EST -05:00
|
347
|
+
# t.change(year: 2020) # => Tue, 14 Apr 2020 11:45:15 EST -05:00
|
348
|
+
# t.change(hour: 12) # => Fri, 14 Apr 2017 12:00:00 EST -05:00
|
349
|
+
# t.change(min: 30) # => Fri, 14 Apr 2017 11:30:00 EST -05:00
|
350
|
+
# t.change(offset: "-10:00") # => Fri, 14 Apr 2017 11:45:15 HST -10:00
|
351
|
+
# t.change(zone: "Hawaii") # => Fri, 14 Apr 2017 11:45:15 HST -10:00
|
352
|
+
def change(options)
|
353
|
+
if options[:zone] && options[:offset]
|
354
|
+
raise ArgumentError, "Can't change both :offset and :zone at the same time: #{options.inspect}"
|
355
|
+
end
|
356
|
+
|
357
|
+
new_time = time.change(options)
|
358
|
+
|
359
|
+
if options[:zone]
|
360
|
+
new_zone = ::Time.find_zone(options[:zone])
|
361
|
+
elsif options[:offset]
|
362
|
+
new_zone = ::Time.find_zone(new_time.utc_offset)
|
363
|
+
end
|
364
|
+
|
365
|
+
new_zone ||= time_zone
|
366
|
+
periods = new_zone.periods_for_local(new_time)
|
367
|
+
|
368
|
+
self.class.new(nil, new_zone, new_time, periods.include?(period) ? period : nil)
|
369
|
+
end
|
370
|
+
|
371
|
+
# Uses Date to provide precise Time calculations for years, months, and days
|
372
|
+
# according to the proleptic Gregorian calendar. The result is returned as a
|
373
|
+
# new TimeWithZone object.
|
374
|
+
#
|
375
|
+
# The +options+ parameter takes a hash with any of these keys:
|
376
|
+
# <tt>:years</tt>, <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>,
|
377
|
+
# <tt>:hours</tt>, <tt>:minutes</tt>, <tt>:seconds</tt>.
|
378
|
+
#
|
379
|
+
# If advancing by a value of variable length (i.e., years, weeks, months,
|
380
|
+
# days), move forward from #time, otherwise move forward from #utc, for
|
381
|
+
# accuracy when moving across DST boundaries.
|
382
|
+
#
|
383
|
+
# Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
|
384
|
+
# now = Time.zone.now # => Sun, 02 Nov 2014 01:26:28 EDT -04:00
|
385
|
+
# now.advance(seconds: 1) # => Sun, 02 Nov 2014 01:26:29 EDT -04:00
|
386
|
+
# now.advance(minutes: 1) # => Sun, 02 Nov 2014 01:27:28 EDT -04:00
|
387
|
+
# now.advance(hours: 1) # => Sun, 02 Nov 2014 01:26:28 EST -05:00
|
388
|
+
# now.advance(days: 1) # => Mon, 03 Nov 2014 01:26:28 EST -05:00
|
389
|
+
# now.advance(weeks: 1) # => Sun, 09 Nov 2014 01:26:28 EST -05:00
|
390
|
+
# now.advance(months: 1) # => Tue, 02 Dec 2014 01:26:28 EST -05:00
|
391
|
+
# now.advance(years: 1) # => Mon, 02 Nov 2015 01:26:28 EST -05:00
|
290
392
|
def advance(options)
|
291
393
|
# If we're advancing a value of variable length (i.e., years, weeks, months, days), advance from #time,
|
292
394
|
# otherwise advance from #utc, for accuracy when moving across DST boundaries
|
@@ -305,23 +407,44 @@ module ActiveSupport
|
|
305
407
|
EOV
|
306
408
|
end
|
307
409
|
|
410
|
+
# Returns Array of parts of Time in sequence of
|
411
|
+
# [seconds, minutes, hours, day, month, year, weekday, yearday, dst?, zone].
|
412
|
+
#
|
413
|
+
# now = Time.zone.now # => Tue, 18 Aug 2015 02:29:27 UTC +00:00
|
414
|
+
# now.to_a # => [27, 29, 2, 18, 8, 2015, 2, 230, false, "UTC"]
|
308
415
|
def to_a
|
309
416
|
[time.sec, time.min, time.hour, time.day, time.mon, time.year, time.wday, time.yday, dst?, zone]
|
310
417
|
end
|
311
418
|
|
419
|
+
# Returns the object's date and time as a floating point number of seconds
|
420
|
+
# since the Epoch (January 1, 1970 00:00 UTC).
|
421
|
+
#
|
422
|
+
# Time.zone.now.to_f # => 1417709320.285418
|
312
423
|
def to_f
|
313
424
|
utc.to_f
|
314
425
|
end
|
315
426
|
|
427
|
+
# Returns the object's date and time as an integer number of seconds
|
428
|
+
# since the Epoch (January 1, 1970 00:00 UTC).
|
429
|
+
#
|
430
|
+
# Time.zone.now.to_i # => 1417709320
|
316
431
|
def to_i
|
317
432
|
utc.to_i
|
318
433
|
end
|
319
434
|
alias_method :tv_sec, :to_i
|
320
435
|
|
436
|
+
# Returns the object's date and time as a rational number of seconds
|
437
|
+
# since the Epoch (January 1, 1970 00:00 UTC).
|
438
|
+
#
|
439
|
+
# Time.zone.now.to_r # => (708854548642709/500000)
|
321
440
|
def to_r
|
322
441
|
utc.to_r
|
323
442
|
end
|
324
443
|
|
444
|
+
# Returns an instance of DateTime with the timezone's UTC offset
|
445
|
+
#
|
446
|
+
# Time.zone.now.to_datetime # => Tue, 18 Aug 2015 02:32:20 +0000
|
447
|
+
# Time.current.in_time_zone('Hawaii').to_datetime # => Mon, 17 Aug 2015 16:32:20 -1000
|
325
448
|
def to_datetime
|
326
449
|
@to_datetime ||= utc.to_datetime.new_offset(Rational(utc_offset, 86_400))
|
327
450
|
end
|
@@ -348,6 +471,11 @@ module ActiveSupport
|
|
348
471
|
end
|
349
472
|
alias_method :kind_of?, :is_a?
|
350
473
|
|
474
|
+
# An instance of ActiveSupport::TimeWithZone is never blank
|
475
|
+
def blank?
|
476
|
+
false
|
477
|
+
end
|
478
|
+
|
351
479
|
def freeze
|
352
480
|
# preload instance variables before freezing
|
353
481
|
period; utc; time; to_datetime; to_time
|
@@ -382,7 +510,7 @@ module ActiveSupport
|
|
382
510
|
def method_missing(sym, *args, &block)
|
383
511
|
wrap_with_time_zone time.__send__(sym, *args, &block)
|
384
512
|
rescue NoMethodError => e
|
385
|
-
raise e, e.message.sub(time.inspect,
|
513
|
+
raise e, e.message.sub(time.inspect, inspect), e.backtrace
|
386
514
|
end
|
387
515
|
|
388
516
|
private
|
@@ -400,11 +528,13 @@ module ActiveSupport
|
|
400
528
|
end
|
401
529
|
|
402
530
|
def transfer_time_values_to_utc_constructor(time)
|
531
|
+
# avoid creating another Time object if possible
|
532
|
+
return time if time.instance_of?(::Time) && time.utc?
|
403
533
|
::Time.utc(time.year, time.month, time.day, time.hour, time.min, time.sec + time.subsec)
|
404
534
|
end
|
405
535
|
|
406
536
|
def duration_of_variable_length?(obj)
|
407
|
-
ActiveSupport::Duration === obj && obj.parts.any? {|p| [:years, :months, :days].include?(p[0]) }
|
537
|
+
ActiveSupport::Duration === obj && obj.parts.any? { |p| [:years, :months, :weeks, :days].include?(p[0]) }
|
408
538
|
end
|
409
539
|
|
410
540
|
def wrap_with_time_zone(time)
|