activesupport 6.1.0 → 7.1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1075 -325
- data/MIT-LICENSE +1 -1
- data/README.rdoc +7 -7
- data/lib/active_support/actionable_error.rb +4 -2
- data/lib/active_support/array_inquirer.rb +2 -2
- data/lib/active_support/backtrace_cleaner.rb +32 -7
- data/lib/active_support/benchmarkable.rb +3 -2
- data/lib/active_support/broadcast_logger.rb +251 -0
- data/lib/active_support/builder.rb +1 -1
- data/lib/active_support/cache/coder.rb +153 -0
- data/lib/active_support/cache/entry.rb +134 -0
- data/lib/active_support/cache/file_store.rb +53 -20
- data/lib/active_support/cache/mem_cache_store.rb +201 -62
- data/lib/active_support/cache/memory_store.rb +86 -24
- data/lib/active_support/cache/null_store.rb +16 -2
- data/lib/active_support/cache/redis_cache_store.rb +186 -193
- data/lib/active_support/cache/serializer_with_fallback.rb +175 -0
- data/lib/active_support/cache/strategy/local_cache.rb +63 -71
- data/lib/active_support/cache.rb +487 -249
- data/lib/active_support/callbacks.rb +227 -105
- data/lib/active_support/code_generator.rb +70 -0
- data/lib/active_support/concern.rb +9 -7
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +44 -7
- data/lib/active_support/concurrency/null_lock.rb +13 -0
- data/lib/active_support/concurrency/share_lock.rb +2 -2
- data/lib/active_support/configurable.rb +18 -5
- data/lib/active_support/configuration_file.rb +7 -2
- data/lib/active_support/core_ext/array/access.rb +1 -5
- data/lib/active_support/core_ext/array/conversions.rb +15 -13
- 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/big_decimal/conversions.rb +1 -1
- data/lib/active_support/core_ext/class/subclasses.rb +37 -26
- 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 +16 -15
- data/lib/active_support/core_ext/date_and_time/calculations.rb +14 -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 +19 -15
- data/lib/active_support/core_ext/digest/uuid.rb +30 -13
- data/lib/active_support/core_ext/enumerable.rb +85 -83
- data/lib/active_support/core_ext/erb/util.rb +196 -0
- data/lib/active_support/core_ext/file/atomic.rb +3 -1
- data/lib/active_support/core_ext/hash/conversions.rb +1 -2
- data/lib/active_support/core_ext/hash/deep_merge.rb +22 -14
- 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 +8 -0
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +49 -22
- data/lib/active_support/core_ext/module/concerning.rb +6 -6
- data/lib/active_support/core_ext/module/delegation.rb +81 -43
- data/lib/active_support/core_ext/module/deprecation.rb +15 -12
- data/lib/active_support/core_ext/module/introspection.rb +0 -1
- data/lib/active_support/core_ext/name_error.rb +2 -8
- data/lib/active_support/core_ext/numeric/bytes.rb +9 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +82 -77
- 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 +17 -1
- data/lib/active_support/core_ext/object/duplicable.rb +31 -11
- data/lib/active_support/core_ext/object/inclusion.rb +13 -5
- data/lib/active_support/core_ext/object/instance_variables.rb +22 -12
- data/lib/active_support/core_ext/object/json.rb +49 -27
- 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.rb +44 -0
- data/lib/active_support/core_ext/object/with_options.rb +25 -6
- data/lib/active_support/core_ext/object.rb +1 -0
- data/lib/active_support/core_ext/pathname/blank.rb +16 -0
- data/lib/active_support/core_ext/pathname/existence.rb +23 -0
- data/lib/active_support/core_ext/pathname.rb +4 -0
- data/lib/active_support/core_ext/range/compare_range.rb +0 -25
- data/lib/active_support/core_ext/range/conversions.rb +34 -13
- data/lib/active_support/core_ext/range/each.rb +1 -1
- data/lib/active_support/core_ext/range/overlap.rb +40 -0
- data/lib/active_support/core_ext/range.rb +1 -2
- data/lib/active_support/core_ext/securerandom.rb +25 -13
- data/lib/active_support/core_ext/string/conversions.rb +2 -2
- data/lib/active_support/core_ext/string/filters.rb +21 -15
- data/lib/active_support/core_ext/string/indent.rb +1 -1
- data/lib/active_support/core_ext/string/inflections.rb +17 -10
- data/lib/active_support/core_ext/string/inquiry.rb +1 -1
- data/lib/active_support/core_ext/string/output_safety.rb +85 -165
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +0 -8
- data/lib/active_support/core_ext/thread/backtrace/location.rb +12 -0
- data/lib/active_support/core_ext/time/calculations.rb +30 -8
- data/lib/active_support/core_ext/time/conversions.rb +15 -13
- data/lib/active_support/core_ext/time/zones.rb +12 -28
- data/lib/active_support/core_ext.rb +2 -1
- data/lib/active_support/current_attributes.rb +47 -20
- data/lib/active_support/deep_mergeable.rb +53 -0
- data/lib/active_support/dependencies/autoload.rb +17 -12
- 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 +66 -40
- data/lib/active_support/deprecation/constant_accessor.rb +5 -4
- data/lib/active_support/deprecation/deprecators.rb +104 -0
- data/lib/active_support/deprecation/disallowed.rb +6 -8
- data/lib/active_support/deprecation/instance_delegator.rb +31 -4
- data/lib/active_support/deprecation/method_wrappers.rb +9 -26
- data/lib/active_support/deprecation/proxy_wrappers.rb +38 -23
- data/lib/active_support/deprecation/reporting.rb +43 -26
- data/lib/active_support/deprecation.rb +32 -5
- data/lib/active_support/deprecator.rb +7 -0
- data/lib/active_support/descendants_tracker.rb +150 -72
- 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 -3
- data/lib/active_support/duration.rb +83 -52
- data/lib/active_support/encrypted_configuration.rb +72 -9
- data/lib/active_support/encrypted_file.rb +29 -13
- data/lib/active_support/environment_inquirer.rb +23 -3
- data/lib/active_support/error_reporter/test_helper.rb +15 -0
- data/lib/active_support/error_reporter.rb +203 -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 +44 -22
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/file_update_checker.rb +4 -2
- data/lib/active_support/fork_tracker.rb +28 -11
- data/lib/active_support/gem_version.rb +4 -4
- data/lib/active_support/gzip.rb +2 -0
- data/lib/active_support/hash_with_indifferent_access.rb +44 -19
- data/lib/active_support/html_safe_translation.rb +53 -0
- data/lib/active_support/i18n.rb +2 -1
- data/lib/active_support/i18n_railtie.rb +21 -14
- data/lib/active_support/inflector/inflections.rb +25 -7
- data/lib/active_support/inflector/methods.rb +50 -64
- data/lib/active_support/inflector/transliterate.rb +4 -2
- data/lib/active_support/isolated_execution_state.rb +76 -0
- data/lib/active_support/json/decoding.rb +2 -1
- data/lib/active_support/json/encoding.rb +27 -45
- data/lib/active_support/key_generator.rb +31 -6
- data/lib/active_support/lazy_load_hooks.rb +33 -7
- data/lib/active_support/locale/en.yml +4 -2
- data/lib/active_support/log_subscriber/test_helper.rb +2 -2
- data/lib/active_support/log_subscriber.rb +97 -35
- data/lib/active_support/logger.rb +9 -60
- data/lib/active_support/logger_thread_safe_level.rb +11 -34
- data/lib/active_support/message_encryptor.rb +206 -56
- data/lib/active_support/message_encryptors.rb +141 -0
- data/lib/active_support/message_pack/cache_serializer.rb +23 -0
- data/lib/active_support/message_pack/extensions.rb +292 -0
- data/lib/active_support/message_pack/serializer.rb +63 -0
- data/lib/active_support/message_pack.rb +50 -0
- data/lib/active_support/message_verifier.rb +235 -84
- data/lib/active_support/message_verifiers.rb +135 -0
- data/lib/active_support/messages/codec.rb +65 -0
- data/lib/active_support/messages/metadata.rb +112 -46
- data/lib/active_support/messages/rotation_coordinator.rb +93 -0
- data/lib/active_support/messages/rotator.rb +34 -32
- data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
- data/lib/active_support/multibyte/chars.rb +12 -11
- data/lib/active_support/multibyte/unicode.rb +9 -49
- data/lib/active_support/multibyte.rb +1 -1
- data/lib/active_support/notifications/fanout.rb +304 -114
- data/lib/active_support/notifications/instrumenter.rb +117 -35
- data/lib/active_support/notifications.rb +25 -25
- data/lib/active_support/number_helper/number_converter.rb +14 -7
- 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 +4 -4
- data/lib/active_support/number_helper/number_to_phone_converter.rb +2 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +10 -6
- data/lib/active_support/number_helper/rounding_helper.rb +2 -6
- data/lib/active_support/number_helper.rb +379 -319
- data/lib/active_support/option_merger.rb +10 -18
- data/lib/active_support/ordered_hash.rb +4 -4
- data/lib/active_support/ordered_options.rb +15 -1
- data/lib/active_support/parameter_filter.rb +105 -81
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/railtie.rb +83 -21
- data/lib/active_support/reloader.rb +13 -5
- data/lib/active_support/rescuable.rb +18 -16
- data/lib/active_support/ruby_features.rb +7 -0
- data/lib/active_support/secure_compare_rotator.rb +18 -11
- data/lib/active_support/security_utils.rb +1 -1
- data/lib/active_support/string_inquirer.rb +3 -3
- data/lib/active_support/subscriber.rb +11 -40
- data/lib/active_support/syntax_error_proxy.rb +60 -0
- data/lib/active_support/tagged_logging.rb +65 -25
- data/lib/active_support/test_case.rb +166 -27
- data/lib/active_support/testing/assertions.rb +61 -15
- data/lib/active_support/testing/autorun.rb +0 -2
- data/lib/active_support/testing/constant_stubbing.rb +32 -0
- data/lib/active_support/testing/deprecation.rb +53 -2
- data/lib/active_support/testing/error_reporter_assertions.rb +107 -0
- data/lib/active_support/testing/isolation.rb +30 -29
- data/lib/active_support/testing/method_call_assertions.rb +24 -11
- 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 +81 -0
- data/lib/active_support/testing/setup_and_teardown.rb +2 -0
- data/lib/active_support/testing/stream.rb +4 -6
- data/lib/active_support/testing/strict_warnings.rb +39 -0
- data/lib/active_support/testing/tagged_logging.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +49 -16
- data/lib/active_support/time_with_zone.rb +39 -28
- data/lib/active_support/values/time_zone.rb +50 -18
- data/lib/active_support/version.rb +1 -1
- data/lib/active_support/xml_mini/jdom.rb +4 -11
- 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 +5 -5
- data/lib/active_support/xml_mini/nokogirisax.rb +2 -2
- data/lib/active_support/xml_mini/rexml.rb +2 -2
- data/lib/active_support/xml_mini.rb +7 -6
- data/lib/active_support.rb +28 -1
- metadata +150 -18
- data/lib/active_support/core_ext/marshal.rb +0 -26
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +0 -28
- data/lib/active_support/core_ext/range/overlaps.rb +0 -10
- data/lib/active_support/core_ext/uri.rb +0 -29
- data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -117
- data/lib/active_support/per_thread_registry.rb +0 -60
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
$VERBOSE = true
|
4
|
+
Warning[:deprecated] = true
|
5
|
+
|
6
|
+
module ActiveSupport
|
7
|
+
module RaiseWarnings # :nodoc:
|
8
|
+
PROJECT_ROOT = File.expand_path("../../../../", __dir__)
|
9
|
+
ALLOWED_WARNINGS = Regexp.union(
|
10
|
+
/circular require considered harmful.*delayed_job/, # Bug in delayed job.
|
11
|
+
|
12
|
+
# Expected non-verbose warning emitted by Rails.
|
13
|
+
/Ignoring .*\.yml because it has expired/,
|
14
|
+
/Failed to validate the schema cache because/,
|
15
|
+
)
|
16
|
+
|
17
|
+
SUPPRESSED_WARNINGS = Regexp.union(
|
18
|
+
# TODO: remove if https://github.com/mikel/mail/pull/1557 or similar fix
|
19
|
+
%r{/lib/mail/parsers/.*statement not reached},
|
20
|
+
%r{/lib/mail/parsers/.*assigned but unused variable - disp_type_s},
|
21
|
+
%r{/lib/mail/parsers/.*assigned but unused variable - testEof}
|
22
|
+
)
|
23
|
+
|
24
|
+
def warn(message, *)
|
25
|
+
return if SUPPRESSED_WARNINGS.match?(message)
|
26
|
+
|
27
|
+
super
|
28
|
+
|
29
|
+
return unless message.include?(PROJECT_ROOT)
|
30
|
+
return if ALLOWED_WARNINGS.match?(message)
|
31
|
+
return unless ENV["RAILS_STRICT_WARNINGS"] || ENV["CI"]
|
32
|
+
|
33
|
+
raise message
|
34
|
+
end
|
35
|
+
ruby2_keywords :warn if respond_to?(:ruby2_keywords, true)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
Warning.singleton_class.prepend(ActiveSupport::RaiseWarnings)
|
@@ -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
|
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
require "active_support/core_ext/module/redefine_method"
|
4
4
|
require "active_support/core_ext/time/calculations"
|
5
|
-
require "concurrent/map"
|
6
5
|
|
7
6
|
module ActiveSupport
|
8
7
|
module Testing
|
@@ -11,7 +10,7 @@ module ActiveSupport
|
|
11
10
|
Stub = Struct.new(:object, :method_name, :original_method)
|
12
11
|
|
13
12
|
def initialize
|
14
|
-
@stubs =
|
13
|
+
@stubs = Hash.new { |h, k| h[k] = {} }
|
15
14
|
end
|
16
15
|
|
17
16
|
# Stubs object.method_name with the given block
|
@@ -26,7 +25,7 @@ module ActiveSupport
|
|
26
25
|
unstub_object(stub)
|
27
26
|
end
|
28
27
|
|
29
|
-
new_name = "__simple_stub__#{method_name}"
|
28
|
+
new_name = "__simple_stub__#{method_name}__#{object_id}"
|
30
29
|
|
31
30
|
@stubs[object.object_id][method_name] = Stub.new(object, method_name, new_name)
|
32
31
|
|
@@ -76,6 +75,11 @@ module ActiveSupport
|
|
76
75
|
# stubbing +Time.now+, +Date.today+, and +DateTime.now+. The stubs are automatically removed
|
77
76
|
# at the end of the test.
|
78
77
|
#
|
78
|
+
# Note that the usec for the resulting time will be set to 0 to prevent rounding
|
79
|
+
# errors with external services, like MySQL (which will round instead of floor,
|
80
|
+
# leading to off-by-one-second errors), unless the <tt>with_usec</tt> argument
|
81
|
+
# is set to <tt>true</tt>.
|
82
|
+
#
|
79
83
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
80
84
|
# travel 1.day
|
81
85
|
# Time.current # => Sun, 10 Nov 2013 15:34:49 EST -05:00
|
@@ -90,11 +94,11 @@ module ActiveSupport
|
|
90
94
|
# User.create.created_at # => Sun, 10 Nov 2013 15:34:49 EST -05:00
|
91
95
|
# end
|
92
96
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
93
|
-
def travel(duration, &block)
|
94
|
-
travel_to Time.now + duration, &block
|
97
|
+
def travel(duration, with_usec: false, &block)
|
98
|
+
travel_to Time.now + duration, with_usec: with_usec, &block
|
95
99
|
end
|
96
100
|
|
97
|
-
# Changes current time to the given time by stubbing +Time.now+,
|
101
|
+
# Changes current time to the given time by stubbing +Time.now+, +Time.new+,
|
98
102
|
# +Date.today+, and +DateTime.now+ to return the time or date passed into this method.
|
99
103
|
# The stubs are automatically removed at the end of the test.
|
100
104
|
#
|
@@ -115,7 +119,8 @@ module ActiveSupport
|
|
115
119
|
#
|
116
120
|
# Note that the usec for the time passed will be set to 0 to prevent rounding
|
117
121
|
# errors with external services, like MySQL (which will round instead of floor,
|
118
|
-
# leading to off-by-one-second errors)
|
122
|
+
# leading to off-by-one-second errors), unless the <tt>with_usec</tt> argument
|
123
|
+
# is set to <tt>true</tt>.
|
119
124
|
#
|
120
125
|
# This method also accepts a block, which will return the current time back to its original
|
121
126
|
# state at the end of the block:
|
@@ -125,8 +130,8 @@ module ActiveSupport
|
|
125
130
|
# Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
|
126
131
|
# end
|
127
132
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
128
|
-
def travel_to(date_or_time)
|
129
|
-
if block_given? &&
|
133
|
+
def travel_to(date_or_time, with_usec: false)
|
134
|
+
if block_given? && in_block
|
130
135
|
travel_to_nested_block_call = <<~MSG
|
131
136
|
|
132
137
|
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 +161,45 @@ module ActiveSupport
|
|
156
161
|
|
157
162
|
if date_or_time.is_a?(Date) && !date_or_time.is_a?(DateTime)
|
158
163
|
now = date_or_time.midnight.to_time
|
164
|
+
elsif date_or_time.is_a?(String)
|
165
|
+
now = Time.zone.parse(date_or_time)
|
166
|
+
elsif with_usec
|
167
|
+
now = date_or_time.to_time
|
159
168
|
else
|
160
169
|
now = date_or_time.to_time.change(usec: 0)
|
161
170
|
end
|
162
171
|
|
163
|
-
|
164
|
-
|
165
|
-
|
172
|
+
# +now+ must be in local system timezone, because +Time.at(now)+
|
173
|
+
# and +now.to_date+ (see stubs below) will use +now+'s timezone too!
|
174
|
+
now = now.getlocal
|
175
|
+
|
176
|
+
stubs = simple_stubs
|
177
|
+
stubbed_time = Time.now if stubs.stubbing(Time, :now)
|
178
|
+
stubs.stub_object(Time, :now) { at(now) }
|
179
|
+
|
180
|
+
stubs.stub_object(Time, :new) do |*args, **options|
|
181
|
+
if args.empty? && options.empty?
|
182
|
+
at(now)
|
183
|
+
else
|
184
|
+
stub = stubs.stubbing(Time, :new)
|
185
|
+
Time.send(stub.original_method, *args, **options)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
stubs.stub_object(Date, :today) { jd(now.to_date.jd) }
|
190
|
+
stubs.stub_object(DateTime, :now) { jd(now.to_date.jd, now.hour, now.min, now.sec, Rational(now.utc_offset, 86400)) }
|
166
191
|
|
167
192
|
if block_given?
|
168
193
|
begin
|
194
|
+
self.in_block = true
|
169
195
|
yield
|
170
196
|
ensure
|
171
|
-
|
197
|
+
if stubbed_time
|
198
|
+
travel_to stubbed_time
|
199
|
+
else
|
200
|
+
travel_back
|
201
|
+
end
|
202
|
+
self.in_block = false
|
172
203
|
end
|
173
204
|
end
|
174
205
|
end
|
@@ -206,7 +237,7 @@ module ActiveSupport
|
|
206
237
|
end
|
207
238
|
alias_method :unfreeze_time, :travel_back
|
208
239
|
|
209
|
-
# Calls +travel_to+ with +Time.now+.
|
240
|
+
# Calls +travel_to+ with +Time.now+. Forwards optional <tt>with_usec</tt> argument.
|
210
241
|
#
|
211
242
|
# Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00
|
212
243
|
# freeze_time
|
@@ -222,14 +253,16 @@ module ActiveSupport
|
|
222
253
|
# User.create.created_at # => Sun, 09 Jul 2017 15:34:49 EST -05:00
|
223
254
|
# end
|
224
255
|
# Time.current # => Sun, 09 Jul 2017 15:34:50 EST -05:00
|
225
|
-
def freeze_time(&block)
|
226
|
-
travel_to Time.now, &block
|
256
|
+
def freeze_time(with_usec: false, &block)
|
257
|
+
travel_to Time.now, with_usec: with_usec, &block
|
227
258
|
end
|
228
259
|
|
229
260
|
private
|
230
261
|
def simple_stubs
|
231
262
|
@simple_stubs ||= SimpleStubs.new
|
232
263
|
end
|
264
|
+
|
265
|
+
attr_accessor :in_block
|
233
266
|
end
|
234
267
|
end
|
235
268
|
end
|
@@ -1,17 +1,21 @@
|
|
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"
|
6
8
|
require "active_support/core_ext/date_and_time/compatibility"
|
7
9
|
|
8
10
|
module ActiveSupport
|
11
|
+
# = Active Support \Time With Zone
|
12
|
+
#
|
9
13
|
# A Time-like class that can represent a time in any time zone. Necessary
|
10
14
|
# because standard Ruby Time instances are limited to UTC and the
|
11
15
|
# system's <tt>ENV['TZ']</tt> zone.
|
12
16
|
#
|
13
17
|
# You shouldn't ever need to create a TimeWithZone instance directly via +new+.
|
14
|
-
# Instead use methods +local+, +parse+, +at
|
18
|
+
# Instead use methods +local+, +parse+, +at+, and +now+ on TimeZone instances,
|
15
19
|
# and +in_time_zone+ on Time and DateTime instances.
|
16
20
|
#
|
17
21
|
# Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
|
@@ -31,18 +35,13 @@ module ActiveSupport
|
|
31
35
|
# t.dst? # => true
|
32
36
|
# t.utc_offset # => -14400
|
33
37
|
# t.zone # => "EDT"
|
34
|
-
# t.
|
38
|
+
# t.to_fs(:rfc822) # => "Sun, 18 May 2008 13:27:25 -0400"
|
35
39
|
# t + 1.day # => Mon, 19 May 2008 13:27:25.031505668 EDT -04:00
|
36
40
|
# t.beginning_of_year # => Tue, 01 Jan 2008 00:00:00.000000000 EST -05:00
|
37
41
|
# t > Time.utc(1999) # => true
|
38
42
|
# t.is_a?(Time) # => true
|
39
43
|
# t.is_a?(ActiveSupport::TimeWithZone) # => true
|
40
44
|
class TimeWithZone
|
41
|
-
# Report class name as 'Time' to thwart type checking.
|
42
|
-
def self.name
|
43
|
-
"Time"
|
44
|
-
end
|
45
|
-
|
46
45
|
PRECISIONS = Hash.new { |h, n| h[n] = "%FT%T.%#{n}N" }
|
47
46
|
PRECISIONS[0] = "%FT%T"
|
48
47
|
|
@@ -69,7 +68,7 @@ module ActiveSupport
|
|
69
68
|
alias_method :getutc, :utc
|
70
69
|
alias_method :gmtime, :utc
|
71
70
|
|
72
|
-
# Returns the underlying TZInfo::TimezonePeriod
|
71
|
+
# Returns the underlying +TZInfo::TimezonePeriod+.
|
73
72
|
def period
|
74
73
|
@period ||= time_zone.period_for_utc(@utc)
|
75
74
|
end
|
@@ -172,12 +171,11 @@ module ActiveSupport
|
|
172
171
|
end
|
173
172
|
end
|
174
173
|
|
175
|
-
def init_with(coder)
|
174
|
+
def init_with(coder) # :nodoc:
|
176
175
|
initialize(coder["utc"], coder["zone"], coder["time"])
|
177
176
|
end
|
178
177
|
|
179
|
-
def encode_with(coder)
|
180
|
-
coder.tag = "!ruby/object:ActiveSupport::TimeWithZone"
|
178
|
+
def encode_with(coder) # :nodoc:
|
181
179
|
coder.map = { "utc" => utc, "zone" => time_zone, "time" => time }
|
182
180
|
end
|
183
181
|
|
@@ -194,25 +192,34 @@ module ActiveSupport
|
|
194
192
|
#
|
195
193
|
# Time.zone.now.rfc2822 # => "Tue, 01 Jan 2013 04:51:39 +0000"
|
196
194
|
def rfc2822
|
197
|
-
|
195
|
+
to_fs(:rfc822)
|
198
196
|
end
|
199
197
|
alias_method :rfc822, :rfc2822
|
200
198
|
|
201
199
|
# Returns a string of the object's date and time.
|
200
|
+
def to_s
|
201
|
+
"#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}" # mimicking Ruby Time#to_s format
|
202
|
+
end
|
203
|
+
|
204
|
+
# Returns a string of the object's date and time.
|
205
|
+
#
|
206
|
+
# This method is aliased to <tt>to_formatted_s</tt>.
|
207
|
+
#
|
202
208
|
# Accepts an optional <tt>format</tt>:
|
203
209
|
# * <tt>:default</tt> - default value, mimics Ruby Time#to_s format.
|
204
|
-
# * <tt>:db</tt> - format outputs time in UTC :db time. See Time#
|
205
|
-
# * Any key in
|
206
|
-
def
|
210
|
+
# * <tt>:db</tt> - format outputs time in UTC :db time. See Time#to_fs(:db).
|
211
|
+
# * Any key in +Time::DATE_FORMATS+ can be used. See active_support/core_ext/time/conversions.rb.
|
212
|
+
def to_fs(format = :default)
|
207
213
|
if format == :db
|
208
|
-
utc.
|
214
|
+
utc.to_fs(format)
|
209
215
|
elsif formatter = ::Time::DATE_FORMATS[format]
|
210
216
|
formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
|
211
217
|
else
|
212
|
-
|
218
|
+
# Change to to_s when deprecation is gone.
|
219
|
+
"#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}"
|
213
220
|
end
|
214
221
|
end
|
215
|
-
alias_method :to_formatted_s, :
|
222
|
+
alias_method :to_formatted_s, :to_fs
|
216
223
|
|
217
224
|
# Replaces <tt>%Z</tt> directive with +zone before passing to Time#strftime,
|
218
225
|
# so that zone information is correct.
|
@@ -301,9 +308,8 @@ module ActiveSupport
|
|
301
308
|
alias_method :in, :+
|
302
309
|
|
303
310
|
# Subtracts an interval of time and returns a new TimeWithZone object unless
|
304
|
-
# the other value
|
305
|
-
#
|
306
|
-
# object's time and the +other+ time.
|
311
|
+
# the other value +acts_like?+ time. In which case, it will subtract the
|
312
|
+
# other time and return the difference in seconds as a Float.
|
307
313
|
#
|
308
314
|
# Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
|
309
315
|
# now = Time.zone.now # => Mon, 03 Nov 2014 00:26:28.725182881 EST -05:00
|
@@ -359,8 +365,8 @@ module ActiveSupport
|
|
359
365
|
# Returns a new +ActiveSupport::TimeWithZone+ where one or more of the elements have
|
360
366
|
# been changed according to the +options+ parameter. The time options (<tt>:hour</tt>,
|
361
367
|
# <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+
|
368
|
+
# so if only the hour is passed, then minute, sec, usec, and nsec is set to 0. If the
|
369
|
+
# hour and minute is passed, then sec, usec, and nsec is set to 0. The +options+
|
364
370
|
# parameter takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>,
|
365
371
|
# <tt>:day</tt>, <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>,
|
366
372
|
# <tt>:nsec</tt>, <tt>:offset</tt>, <tt>:zone</tt>. Pass either <tt>:usec</tt>
|
@@ -440,7 +446,7 @@ module ActiveSupport
|
|
440
446
|
[time.sec, time.min, time.hour, time.day, time.mon, time.year, time.wday, time.yday, dst?, zone]
|
441
447
|
end
|
442
448
|
|
443
|
-
# Returns the object's date and time as a floating
|
449
|
+
# Returns the object's date and time as a floating-point number of seconds
|
444
450
|
# since the Epoch (January 1, 1970 00:00 UTC).
|
445
451
|
#
|
446
452
|
# Time.zone.now.to_f # => 1417709320.285418
|
@@ -531,10 +537,10 @@ module ActiveSupport
|
|
531
537
|
|
532
538
|
# Send the missing method to +time+ instance, and wrap result in a new
|
533
539
|
# TimeWithZone with the existing +time_zone+.
|
534
|
-
def method_missing(
|
535
|
-
wrap_with_time_zone time.__send__(
|
540
|
+
def method_missing(...)
|
541
|
+
wrap_with_time_zone time.__send__(...)
|
536
542
|
rescue NoMethodError => e
|
537
|
-
raise e, e.message.sub(time.inspect, inspect), e.backtrace
|
543
|
+
raise e, e.message.sub(time.inspect, inspect).sub("Time", "ActiveSupport::TimeWithZone"), e.backtrace
|
538
544
|
end
|
539
545
|
|
540
546
|
private
|
@@ -568,7 +574,7 @@ module ActiveSupport
|
|
568
574
|
end
|
569
575
|
|
570
576
|
def duration_of_variable_length?(obj)
|
571
|
-
ActiveSupport::Duration === obj && obj.
|
577
|
+
ActiveSupport::Duration === obj && obj.variable?
|
572
578
|
end
|
573
579
|
|
574
580
|
def wrap_with_time_zone(time)
|
@@ -583,3 +589,8 @@ module ActiveSupport
|
|
583
589
|
end
|
584
590
|
end
|
585
591
|
end
|
592
|
+
|
593
|
+
# These prevent Psych from calling `ActiveSupport::TimeWithZone.name`
|
594
|
+
# and triggering the deprecation warning about the change in Rails 7.1.
|
595
|
+
YAML.load_tags["!ruby/object:ActiveSupport::TimeWithZone"] = "ActiveSupport::TimeWithZone"
|
596
|
+
YAML.dump_tags[ActiveSupport::TimeWithZone] = "!ruby/object:ActiveSupport::TimeWithZone"
|
@@ -4,18 +4,20 @@ require "tzinfo"
|
|
4
4
|
require "concurrent/map"
|
5
5
|
|
6
6
|
module ActiveSupport
|
7
|
-
#
|
7
|
+
# = Active Support \Time Zone
|
8
|
+
#
|
9
|
+
# The TimeZone class serves as a wrapper around +TZInfo::Timezone+ instances.
|
8
10
|
# It allows us to do the following:
|
9
11
|
#
|
10
12
|
# * Limit the set of zones provided by TZInfo to a meaningful subset of 134
|
11
13
|
# zones.
|
12
14
|
# * Retrieve and display zones with a friendlier name
|
13
15
|
# (e.g., "Eastern Time (US & Canada)" instead of "America/New_York").
|
14
|
-
# * Lazily load TZInfo::Timezone instances only when they're needed.
|
16
|
+
# * Lazily load +TZInfo::Timezone+ instances only when they're needed.
|
15
17
|
# * Create ActiveSupport::TimeWithZone instances via TimeZone's +local+,
|
16
|
-
# +parse+, +at
|
18
|
+
# +parse+, +at+, and +now+ methods.
|
17
19
|
#
|
18
|
-
# If you set <tt>config.time_zone</tt> in the Rails Application, you can
|
20
|
+
# If you set <tt>config.time_zone</tt> in the \Rails Application, you can
|
19
21
|
# access this TimeZone object via <tt>Time.zone</tt>:
|
20
22
|
#
|
21
23
|
# # application.rb:
|
@@ -27,7 +29,7 @@ module ActiveSupport
|
|
27
29
|
# Time.zone.name # => "Eastern Time (US & Canada)"
|
28
30
|
# Time.zone.now # => Sun, 18 May 2008 14:30:44 EDT -04:00
|
29
31
|
class TimeZone
|
30
|
-
# Keys are Rails TimeZone names, values are TZInfo identifiers.
|
32
|
+
# Keys are \Rails TimeZone names, values are TZInfo identifiers.
|
31
33
|
MAPPING = {
|
32
34
|
"International Date Line West" => "Etc/GMT+12",
|
33
35
|
"Midway Island" => "Pacific/Midway",
|
@@ -159,7 +161,7 @@ module ActiveSupport
|
|
159
161
|
"Yakutsk" => "Asia/Yakutsk",
|
160
162
|
"Darwin" => "Australia/Darwin",
|
161
163
|
"Adelaide" => "Australia/Adelaide",
|
162
|
-
"Canberra" => "Australia/
|
164
|
+
"Canberra" => "Australia/Canberra",
|
163
165
|
"Melbourne" => "Australia/Melbourne",
|
164
166
|
"Sydney" => "Australia/Sydney",
|
165
167
|
"Brisbane" => "Australia/Brisbane",
|
@@ -206,7 +208,9 @@ module ActiveSupport
|
|
206
208
|
TZInfo::Timezone.get(MAPPING[name] || name)
|
207
209
|
end
|
208
210
|
|
211
|
+
# :stopdoc:
|
209
212
|
alias_method :create, :new
|
213
|
+
# :startdoc:
|
210
214
|
|
211
215
|
# Returns a TimeZone instance with the given name, or +nil+ if no
|
212
216
|
# such TimeZone instance exists. (This exists to support the use of
|
@@ -229,12 +233,16 @@ module ActiveSupport
|
|
229
233
|
# Returns +nil+ if no such time zone is known to the system.
|
230
234
|
def [](arg)
|
231
235
|
case arg
|
236
|
+
when self
|
237
|
+
arg
|
232
238
|
when String
|
233
239
|
begin
|
234
240
|
@lazy_zones_map[arg] ||= create(arg)
|
235
241
|
rescue TZInfo::InvalidTimezoneIdentifier
|
236
242
|
nil
|
237
243
|
end
|
244
|
+
when TZInfo::Timezone
|
245
|
+
@lazy_zones_map[arg.name] ||= create(arg.name, nil, arg)
|
238
246
|
when Numeric, ActiveSupport::Duration
|
239
247
|
arg *= 3600 if arg.abs <= 13
|
240
248
|
all.find { |z| z.utc_offset == arg.to_i }
|
@@ -256,7 +264,7 @@ module ActiveSupport
|
|
256
264
|
@country_zones[code] ||= load_country_zones(code)
|
257
265
|
end
|
258
266
|
|
259
|
-
def clear
|
267
|
+
def clear # :nodoc:
|
260
268
|
@lazy_zones_map = Concurrent::Map.new
|
261
269
|
@country_zones = Concurrent::Map.new
|
262
270
|
@zones = nil
|
@@ -290,15 +298,22 @@ module ActiveSupport
|
|
290
298
|
attr_reader :name
|
291
299
|
attr_reader :tzinfo
|
292
300
|
|
301
|
+
##
|
302
|
+
# :singleton-method: create
|
303
|
+
# :call-seq: create(name, utc_offset = nil, tzinfo = nil)
|
304
|
+
#
|
293
305
|
# Create a new TimeZone object with the given name and offset. The
|
294
306
|
# offset is the number of seconds that this time zone is offset from UTC
|
295
307
|
# (GMT). Seconds were chosen as the offset unit because that is the unit
|
296
308
|
# that Ruby uses to represent time zone offsets (see Time#utc_offset).
|
309
|
+
|
310
|
+
# :stopdoc:
|
297
311
|
def initialize(name, utc_offset = nil, tzinfo = nil)
|
298
312
|
@name = name
|
299
313
|
@utc_offset = utc_offset
|
300
314
|
@tzinfo = tzinfo || TimeZone.find_tzinfo(name)
|
301
315
|
end
|
316
|
+
# :startdoc:
|
302
317
|
|
303
318
|
# Returns the offset of this time zone from UTC in seconds.
|
304
319
|
def utc_offset
|
@@ -381,14 +396,28 @@ module ActiveSupport
|
|
381
396
|
# If the string is invalid then an +ArgumentError+ will be raised unlike +parse+
|
382
397
|
# which usually returns +nil+ when given an invalid date string.
|
383
398
|
def iso8601(str)
|
399
|
+
# Historically `Date._iso8601(nil)` returns `{}`, but in the `date` gem versions `3.2.1`, `3.1.2`, `3.0.2`,
|
400
|
+
# and `2.0.1`, `Date._iso8601(nil)` raises `TypeError` https://github.com/ruby/date/issues/39
|
401
|
+
# Future `date` releases are expected to revert back to the original behavior.
|
402
|
+
raise ArgumentError, "invalid date" if str.nil?
|
403
|
+
|
384
404
|
parts = Date._iso8601(str)
|
385
405
|
|
386
|
-
|
406
|
+
year = parts.fetch(:year)
|
407
|
+
|
408
|
+
if parts.key?(:yday)
|
409
|
+
ordinal_date = Date.ordinal(year, parts.fetch(:yday))
|
410
|
+
month = ordinal_date.month
|
411
|
+
day = ordinal_date.day
|
412
|
+
else
|
413
|
+
month = parts.fetch(:mon)
|
414
|
+
day = parts.fetch(:mday)
|
415
|
+
end
|
387
416
|
|
388
417
|
time = Time.new(
|
389
|
-
|
390
|
-
|
391
|
-
|
418
|
+
year,
|
419
|
+
month,
|
420
|
+
day,
|
392
421
|
parts.fetch(:hour, 0),
|
393
422
|
parts.fetch(:min, 0),
|
394
423
|
parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0),
|
@@ -400,6 +429,9 @@ module ActiveSupport
|
|
400
429
|
else
|
401
430
|
TimeWithZone.new(nil, self, time)
|
402
431
|
end
|
432
|
+
|
433
|
+
rescue Date::Error, KeyError
|
434
|
+
raise ArgumentError, "invalid date"
|
403
435
|
end
|
404
436
|
|
405
437
|
# Method for creating new ActiveSupport::TimeWithZone instance in time zone
|
@@ -508,11 +540,11 @@ module ActiveSupport
|
|
508
540
|
# Time#in_time_zone() instead.
|
509
541
|
#
|
510
542
|
# As of tzinfo 2, utc_to_local returns a Time with a non-zero utc_offset.
|
511
|
-
# See the
|
543
|
+
# See the +utc_to_local_returns_utc_offset_times+ config for more info.
|
512
544
|
def utc_to_local(time)
|
513
545
|
tzinfo.utc_to_local(time).yield_self do |t|
|
514
546
|
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)
|
547
|
+
t : Time.utc(t.year, t.month, t.day, t.hour, t.min, t.sec, t.sec_fraction * 1_000_000)
|
516
548
|
end
|
517
549
|
end
|
518
550
|
|
@@ -522,27 +554,27 @@ module ActiveSupport
|
|
522
554
|
tzinfo.local_to_utc(time, dst)
|
523
555
|
end
|
524
556
|
|
525
|
-
# Available so that TimeZone instances respond like TZInfo::Timezone
|
557
|
+
# Available so that TimeZone instances respond like +TZInfo::Timezone+
|
526
558
|
# instances.
|
527
559
|
def period_for_utc(time)
|
528
560
|
tzinfo.period_for_utc(time)
|
529
561
|
end
|
530
562
|
|
531
|
-
# Available so that TimeZone instances respond like TZInfo::Timezone
|
563
|
+
# Available so that TimeZone instances respond like +TZInfo::Timezone+
|
532
564
|
# instances.
|
533
565
|
def period_for_local(time, dst = true)
|
534
566
|
tzinfo.period_for_local(time, dst) { |periods| periods.last }
|
535
567
|
end
|
536
568
|
|
537
|
-
def periods_for_local(time)
|
569
|
+
def periods_for_local(time) # :nodoc:
|
538
570
|
tzinfo.periods_for_local(time)
|
539
571
|
end
|
540
572
|
|
541
|
-
def init_with(coder)
|
573
|
+
def init_with(coder) # :nodoc:
|
542
574
|
initialize(coder["name"])
|
543
575
|
end
|
544
576
|
|
545
|
-
def encode_with(coder)
|
577
|
+
def encode_with(coder) # :nodoc:
|
546
578
|
coder.tag = "!ruby/object:#{self.class}"
|
547
579
|
coder.map = { "name" => tzinfo.name }
|
548
580
|
end
|
@@ -15,18 +15,11 @@ java_import org.xml.sax.Attributes unless defined? Attributes
|
|
15
15
|
java_import org.w3c.dom.Node unless defined? Node
|
16
16
|
|
17
17
|
module ActiveSupport
|
18
|
-
module XmlMini_JDOM
|
18
|
+
module XmlMini_JDOM # :nodoc:
|
19
19
|
extend self
|
20
20
|
|
21
21
|
CONTENT_KEY = "__content__"
|
22
22
|
|
23
|
-
NODE_TYPE_NAMES = %w{ATTRIBUTE_NODE CDATA_SECTION_NODE COMMENT_NODE DOCUMENT_FRAGMENT_NODE
|
24
|
-
DOCUMENT_NODE DOCUMENT_TYPE_NODE ELEMENT_NODE ENTITY_NODE ENTITY_REFERENCE_NODE NOTATION_NODE
|
25
|
-
PROCESSING_INSTRUCTION_NODE TEXT_NODE}
|
26
|
-
|
27
|
-
node_type_map = {}
|
28
|
-
NODE_TYPE_NAMES.each { |type| node_type_map[Node.send(type)] = type }
|
29
|
-
|
30
23
|
# Parse an XML Document string or IO into a simple hash using Java's jdom.
|
31
24
|
# data::
|
32
25
|
# XML Document string or IO to parse
|
@@ -80,7 +73,7 @@ module ActiveSupport
|
|
80
73
|
if child_nodes.length > 0
|
81
74
|
(0...child_nodes.length).each do |i|
|
82
75
|
child = child_nodes.item(i)
|
83
|
-
merge_element!(hash, child, depth - 1) unless child.node_type == Node
|
76
|
+
merge_element!(hash, child, depth - 1) unless child.node_type == Node::TEXT_NODE
|
84
77
|
end
|
85
78
|
merge_texts!(hash, element) unless empty_content?(element)
|
86
79
|
hash
|
@@ -156,7 +149,7 @@ module ActiveSupport
|
|
156
149
|
child_nodes = element.child_nodes
|
157
150
|
(0...child_nodes.length).each do |i|
|
158
151
|
item = child_nodes.item(i)
|
159
|
-
if item.node_type == Node
|
152
|
+
if item.node_type == Node::TEXT_NODE
|
160
153
|
texts << item.get_data
|
161
154
|
end
|
162
155
|
end
|
@@ -172,7 +165,7 @@ module ActiveSupport
|
|
172
165
|
child_nodes = element.child_nodes
|
173
166
|
(0...child_nodes.length).each do |i|
|
174
167
|
item = child_nodes.item(i)
|
175
|
-
if item.node_type == Node
|
168
|
+
if item.node_type == Node::TEXT_NODE
|
176
169
|
text << item.get_data.strip
|
177
170
|
end
|
178
171
|
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.
|