activesupport 6.0.0.rc1 → 6.0.3.rc1
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 +165 -2
- data/README.rdoc +1 -1
- data/lib/active_support/backtrace_cleaner.rb +0 -1
- data/lib/active_support/cache.rb +29 -28
- data/lib/active_support/cache/file_store.rb +7 -8
- data/lib/active_support/cache/mem_cache_store.rb +8 -8
- data/lib/active_support/cache/memory_store.rb +8 -7
- data/lib/active_support/cache/null_store.rb +3 -3
- data/lib/active_support/cache/redis_cache_store.rb +8 -8
- data/lib/active_support/cache/strategy/local_cache.rb +23 -23
- data/lib/active_support/callbacks.rb +0 -3
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
- data/lib/active_support/concurrency/share_lock.rb +0 -1
- data/lib/active_support/core_ext/array/conversions.rb +5 -5
- data/lib/active_support/core_ext/date_and_time/calculations.rb +0 -30
- data/lib/active_support/core_ext/date_and_time/zones.rb +0 -1
- data/lib/active_support/core_ext/date_time/conversions.rb +0 -1
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/hash/conversions.rb +1 -1
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +2 -2
- data/lib/active_support/core_ext/module/delegation.rb +14 -1
- data/lib/active_support/core_ext/module/introspection.rb +1 -0
- data/lib/active_support/core_ext/object/duplicable.rb +7 -117
- data/lib/active_support/core_ext/object/try.rb +2 -0
- data/lib/active_support/core_ext/range/compare_range.rb +9 -3
- data/lib/active_support/core_ext/range/each.rb +0 -1
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +2 -2
- data/lib/active_support/core_ext/string/filters.rb +1 -1
- data/lib/active_support/core_ext/string/output_safety.rb +2 -1
- data/lib/active_support/core_ext/time/calculations.rb +30 -0
- data/lib/active_support/dependencies.rb +35 -6
- data/lib/active_support/dependencies/zeitwerk_integration.rb +22 -4
- data/lib/active_support/deprecation/method_wrappers.rb +12 -6
- data/lib/active_support/deprecation/proxy_wrappers.rb +28 -3
- data/lib/active_support/descendants_tracker.rb +0 -1
- data/lib/active_support/duration.rb +15 -13
- data/lib/active_support/duration/iso8601_parser.rb +0 -1
- data/lib/active_support/duration/iso8601_serializer.rb +0 -1
- data/lib/active_support/encrypted_file.rb +1 -1
- data/lib/active_support/evented_file_update_checker.rb +11 -2
- data/lib/active_support/file_update_checker.rb +0 -1
- data/lib/active_support/gem_version.rb +1 -1
- data/lib/active_support/i18n_railtie.rb +4 -0
- data/lib/active_support/inflector/inflections.rb +0 -1
- data/lib/active_support/inflector/methods.rb +1 -2
- data/lib/active_support/inflector/transliterate.rb +27 -1
- data/lib/active_support/json/decoding.rb +0 -1
- data/lib/active_support/lazy_load_hooks.rb +0 -1
- data/lib/active_support/locale/en.rb +4 -2
- data/lib/active_support/log_subscriber.rb +0 -1
- data/lib/active_support/logger.rb +1 -1
- data/lib/active_support/logger_thread_safe_level.rb +2 -1
- data/lib/active_support/message_encryptor.rb +1 -1
- data/lib/active_support/message_verifier.rb +2 -2
- data/lib/active_support/messages/metadata.rb +3 -2
- data/lib/active_support/messages/rotator.rb +4 -4
- data/lib/active_support/multibyte/chars.rb +1 -2
- data/lib/active_support/multibyte/unicode.rb +0 -1
- data/lib/active_support/notifications/fanout.rb +2 -2
- data/lib/active_support/notifications/instrumenter.rb +4 -4
- data/lib/active_support/number_helper.rb +4 -0
- data/lib/active_support/number_helper/number_converter.rb +4 -5
- data/lib/active_support/number_helper/number_to_currency_converter.rb +7 -8
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +0 -1
- data/lib/active_support/number_helper/number_to_human_converter.rb +0 -1
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +0 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +0 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +0 -1
- data/lib/active_support/option_merger.rb +21 -3
- data/lib/active_support/ordered_hash.rb +1 -1
- data/lib/active_support/ordered_options.rb +5 -1
- data/lib/active_support/parameter_filter.rb +7 -3
- data/lib/active_support/string_inquirer.rb +0 -1
- data/lib/active_support/testing/parallelization.rb +16 -2
- data/lib/active_support/testing/stream.rb +0 -1
- data/lib/active_support/testing/time_helpers.rb +0 -2
- data/lib/active_support/xml_mini.rb +0 -1
- data/lib/active_support/xml_mini/jdom.rb +0 -1
- metadata +13 -9
@@ -172,7 +172,7 @@ module ActiveSupport
|
|
172
172
|
iv = cipher.random_iv
|
173
173
|
cipher.auth_data = "" if aead_mode?
|
174
174
|
|
175
|
-
encrypted_data = cipher.update(Messages::Metadata.wrap(@serializer.dump(value), metadata_options))
|
175
|
+
encrypted_data = cipher.update(Messages::Metadata.wrap(@serializer.dump(value), **metadata_options))
|
176
176
|
encrypted_data << cipher.final
|
177
177
|
|
178
178
|
blob = "#{::Base64.strict_encode64 encrypted_data}--#{::Base64.strict_encode64 iv}"
|
@@ -172,8 +172,8 @@ module ActiveSupport
|
|
172
172
|
#
|
173
173
|
# other_verifier = ActiveSupport::MessageVerifier.new 'd1ff3r3nt-s3Krit'
|
174
174
|
# other_verifier.verify(signed_message) # => ActiveSupport::MessageVerifier::InvalidSignature
|
175
|
-
def verify(*args)
|
176
|
-
verified(*args) || raise(InvalidSignature)
|
175
|
+
def verify(*args, **options)
|
176
|
+
verified(*args, **options) || raise(InvalidSignature)
|
177
177
|
end
|
178
178
|
|
179
179
|
# Generates a signed message for the provided value.
|
@@ -6,7 +6,8 @@ module ActiveSupport
|
|
6
6
|
module Messages #:nodoc:
|
7
7
|
class Metadata #:nodoc:
|
8
8
|
def initialize(message, expires_at = nil, purpose = nil)
|
9
|
-
@message, @
|
9
|
+
@message, @purpose = message, purpose
|
10
|
+
@expires_at = expires_at.is_a?(String) ? Time.iso8601(expires_at) : expires_at
|
10
11
|
end
|
11
12
|
|
12
13
|
def as_json(options = {})
|
@@ -64,7 +65,7 @@ module ActiveSupport
|
|
64
65
|
end
|
65
66
|
|
66
67
|
def fresh?
|
67
|
-
@expires_at.nil? || Time.now.utc <
|
68
|
+
@expires_at.nil? || Time.now.utc < @expires_at
|
68
69
|
end
|
69
70
|
end
|
70
71
|
end
|
@@ -20,12 +20,12 @@ module ActiveSupport
|
|
20
20
|
def decrypt_and_verify(*args, on_rotation: nil, **options)
|
21
21
|
super
|
22
22
|
rescue MessageEncryptor::InvalidMessage, MessageVerifier::InvalidSignature
|
23
|
-
run_rotations(on_rotation) { |encryptor| encryptor.decrypt_and_verify(*args, options) } || raise
|
23
|
+
run_rotations(on_rotation) { |encryptor| encryptor.decrypt_and_verify(*args, **options) } || raise
|
24
24
|
end
|
25
25
|
|
26
26
|
private
|
27
27
|
def build_rotation(secret = @secret, sign_secret = @sign_secret, options)
|
28
|
-
self.class.new(secret, sign_secret, options)
|
28
|
+
self.class.new(secret, sign_secret, **options)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -33,12 +33,12 @@ module ActiveSupport
|
|
33
33
|
include Rotator
|
34
34
|
|
35
35
|
def verified(*args, on_rotation: nil, **options)
|
36
|
-
super || run_rotations(on_rotation) { |verifier| verifier.verified(*args, options) }
|
36
|
+
super || run_rotations(on_rotation) { |verifier| verifier.verified(*args, **options) }
|
37
37
|
end
|
38
38
|
|
39
39
|
private
|
40
40
|
def build_rotation(secret = @secret, options)
|
41
|
-
self.class.new(secret, options)
|
41
|
+
self.class.new(secret, **options)
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
@@ -122,7 +122,7 @@ module ActiveSupport #:nodoc:
|
|
122
122
|
#
|
123
123
|
# 'こんにちは'.mb_chars.limit(7).to_s # => "こん"
|
124
124
|
def limit(limit)
|
125
|
-
truncate_bytes(limit, omission: nil)
|
125
|
+
chars(@wrapped_string.truncate_bytes(limit, omission: nil))
|
126
126
|
end
|
127
127
|
|
128
128
|
# Capitalizes the first letter of every word, when possible.
|
@@ -207,7 +207,6 @@ module ActiveSupport #:nodoc:
|
|
207
207
|
end
|
208
208
|
|
209
209
|
private
|
210
|
-
|
211
210
|
def chars(string)
|
212
211
|
self.class.new(string)
|
213
212
|
end
|
@@ -180,13 +180,13 @@ module ActiveSupport
|
|
180
180
|
|
181
181
|
def start(name, id, payload)
|
182
182
|
timestack = Thread.current[:_timestack] ||= []
|
183
|
-
timestack.push
|
183
|
+
timestack.push Time.now
|
184
184
|
end
|
185
185
|
|
186
186
|
def finish(name, id, payload)
|
187
187
|
timestack = Thread.current[:_timestack]
|
188
188
|
started = timestack.pop
|
189
|
-
@delegate.call(name, started,
|
189
|
+
@delegate.call(name, started, Time.now, id, payload)
|
190
190
|
end
|
191
191
|
end
|
192
192
|
|
@@ -46,7 +46,6 @@ module ActiveSupport
|
|
46
46
|
end
|
47
47
|
|
48
48
|
private
|
49
|
-
|
50
49
|
def unique_id
|
51
50
|
SecureRandom.hex(10)
|
52
51
|
end
|
@@ -56,8 +55,9 @@ module ActiveSupport
|
|
56
55
|
attr_reader :name, :time, :end, :transaction_id, :payload, :children
|
57
56
|
|
58
57
|
def self.clock_gettime_supported? # :nodoc:
|
59
|
-
defined?(Process::
|
60
|
-
!Gem.win_platform?
|
58
|
+
defined?(Process::CLOCK_THREAD_CPUTIME_ID) &&
|
59
|
+
!Gem.win_platform? &&
|
60
|
+
!RUBY_PLATFORM.match?(/solaris/i)
|
61
61
|
end
|
62
62
|
private_class_method :clock_gettime_supported?
|
63
63
|
|
@@ -142,7 +142,7 @@ module ActiveSupport
|
|
142
142
|
|
143
143
|
if clock_gettime_supported?
|
144
144
|
def now_cpu
|
145
|
-
Process.clock_gettime(Process::
|
145
|
+
Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID)
|
146
146
|
end
|
147
147
|
else
|
148
148
|
def now_cpu
|
@@ -99,6 +99,10 @@ module ActiveSupport
|
|
99
99
|
# number_to_currency(1234567890.506, locale: :fr) # => "1 234 567 890,51 €"
|
100
100
|
# number_to_currency('123a456') # => "$123a456"
|
101
101
|
#
|
102
|
+
# number_to_currency("123a456", raise: true) # => InvalidNumberError
|
103
|
+
#
|
104
|
+
# number_to_currency(-0.456789, precision: 0)
|
105
|
+
# # => "$0"
|
102
106
|
# number_to_currency(-1234567890.50, negative_format: '(%u%n)')
|
103
107
|
# # => "($1,234,567,890.50)"
|
104
108
|
# number_to_currency(1234567890.50, unit: '£', separator: ',', delimiter: '')
|
@@ -136,7 +136,6 @@ module ActiveSupport
|
|
136
136
|
end
|
137
137
|
|
138
138
|
private
|
139
|
-
|
140
139
|
def options
|
141
140
|
@options ||= format_options.merge(opts)
|
142
141
|
end
|
@@ -162,12 +161,12 @@ module ActiveSupport
|
|
162
161
|
options
|
163
162
|
end
|
164
163
|
|
165
|
-
def translate_number_value_with_default(key, i18n_options
|
166
|
-
I18n.translate(key, { default: default_value(key), scope: :number }.merge!(i18n_options))
|
164
|
+
def translate_number_value_with_default(key, **i18n_options)
|
165
|
+
I18n.translate(key, **{ default: default_value(key), scope: :number }.merge!(i18n_options))
|
167
166
|
end
|
168
167
|
|
169
|
-
def translate_in_locale(key, i18n_options
|
170
|
-
translate_number_value_with_default(key, { locale: options[:locale] }.merge(i18n_options))
|
168
|
+
def translate_in_locale(key, **i18n_options)
|
169
|
+
translate_number_value_with_default(key, **{ locale: options[:locale] }.merge(i18n_options))
|
171
170
|
end
|
172
171
|
|
173
172
|
def default_value(key)
|
@@ -9,11 +9,15 @@ module ActiveSupport
|
|
9
9
|
|
10
10
|
def convert
|
11
11
|
number = self.number.to_s.strip
|
12
|
+
number_f = number.to_f
|
12
13
|
format = options[:format]
|
13
14
|
|
14
|
-
if
|
15
|
-
|
16
|
-
|
15
|
+
if number_f.negative?
|
16
|
+
number = number_f.abs
|
17
|
+
|
18
|
+
unless options[:precision] == 0 && number < 0.5
|
19
|
+
format = options[:negative_format]
|
20
|
+
end
|
17
21
|
end
|
18
22
|
|
19
23
|
rounded_number = NumberToRoundedConverter.convert(number, options)
|
@@ -21,11 +25,6 @@ module ActiveSupport
|
|
21
25
|
end
|
22
26
|
|
23
27
|
private
|
24
|
-
|
25
|
-
def absolute_value(number)
|
26
|
-
number.respond_to?(:abs) ? number.abs : number.sub(/\A-/, "")
|
27
|
-
end
|
28
|
-
|
29
28
|
def options
|
30
29
|
@options ||= begin
|
31
30
|
defaults = default_format_options.merge(i18n_opts)
|
@@ -5,7 +5,7 @@ require "active_support/core_ext/hash/deep_merge"
|
|
5
5
|
module ActiveSupport
|
6
6
|
class OptionMerger #:nodoc:
|
7
7
|
instance_methods.each do |method|
|
8
|
-
undef_method(method) if
|
8
|
+
undef_method(method) if !/^(__|instance_eval|class|object_id)/.match?(method)
|
9
9
|
end
|
10
10
|
|
11
11
|
def initialize(context, options)
|
@@ -14,14 +14,32 @@ module ActiveSupport
|
|
14
14
|
|
15
15
|
private
|
16
16
|
def method_missing(method, *arguments, &block)
|
17
|
+
options = nil
|
17
18
|
if arguments.first.is_a?(Proc)
|
18
19
|
proc = arguments.pop
|
19
20
|
arguments << lambda { |*args| @options.deep_merge(proc.call(*args)) }
|
21
|
+
elsif arguments.last.respond_to?(:to_hash)
|
22
|
+
options = @options.deep_merge(arguments.pop)
|
20
23
|
else
|
21
|
-
|
24
|
+
options = @options
|
22
25
|
end
|
23
26
|
|
24
|
-
|
27
|
+
invoke_method(method, arguments, options, &block)
|
28
|
+
end
|
29
|
+
|
30
|
+
if RUBY_VERSION >= "2.7"
|
31
|
+
def invoke_method(method, arguments, options, &block)
|
32
|
+
if options
|
33
|
+
@context.__send__(method, *arguments, **options, &block)
|
34
|
+
else
|
35
|
+
@context.__send__(method, *arguments, &block)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
else
|
39
|
+
def invoke_method(method, arguments, options, &block)
|
40
|
+
arguments << options if options
|
41
|
+
@context.__send__(method, *arguments, &block)
|
42
|
+
end
|
25
43
|
end
|
26
44
|
end
|
27
45
|
end
|
@@ -16,7 +16,7 @@ module ActiveSupport
|
|
16
16
|
# oh.keys # => [:a, :b], this order is guaranteed
|
17
17
|
#
|
18
18
|
# Also, maps the +omap+ feature for YAML files
|
19
|
-
# (See
|
19
|
+
# (See https://yaml.org/type/omap.html) to support ordered items
|
20
20
|
# when loading from yaml.
|
21
21
|
#
|
22
22
|
# <tt>ActiveSupport::OrderedHash</tt> is namespaced to prevent conflicts
|
@@ -39,7 +39,7 @@ module ActiveSupport
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def method_missing(name, *args)
|
42
|
-
name_string = name.to_s
|
42
|
+
name_string = +name.to_s
|
43
43
|
if name_string.chomp!("=")
|
44
44
|
self[name_string] = args.first
|
45
45
|
else
|
@@ -56,6 +56,10 @@ module ActiveSupport
|
|
56
56
|
def respond_to_missing?(name, include_private)
|
57
57
|
true
|
58
58
|
end
|
59
|
+
|
60
|
+
def extractable_options?
|
61
|
+
true
|
62
|
+
end
|
59
63
|
end
|
60
64
|
|
61
65
|
# +InheritableOptions+ provides a constructor to build an +OrderedOptions+
|
@@ -51,7 +51,6 @@ module ActiveSupport
|
|
51
51
|
end
|
52
52
|
|
53
53
|
private
|
54
|
-
|
55
54
|
def compiled_filter
|
56
55
|
@compiled_filter ||= CompiledFilter.compile(@filters, mask: @mask)
|
57
56
|
end
|
@@ -103,14 +102,19 @@ module ActiveSupport
|
|
103
102
|
|
104
103
|
def value_for_key(key, value, parents = [], original_params = nil)
|
105
104
|
parents.push(key) if deep_regexps
|
106
|
-
if regexps.any? { |r| r.match?(key) }
|
105
|
+
if regexps.any? { |r| r.match?(key.to_s) }
|
107
106
|
value = @mask
|
108
107
|
elsif deep_regexps && (joined = parents.join(".")) && deep_regexps.any? { |r| r.match?(joined) }
|
109
108
|
value = @mask
|
110
109
|
elsif value.is_a?(Hash)
|
111
110
|
value = call(value, parents, original_params)
|
112
111
|
elsif value.is_a?(Array)
|
113
|
-
|
112
|
+
# If we don't pop the current parent it will be duplicated as we
|
113
|
+
# process each array value.
|
114
|
+
parents.pop if deep_regexps
|
115
|
+
value = value.map { |v| value_for_key(key, v, parents, original_params) }
|
116
|
+
# Restore the parent stack after processing the array.
|
117
|
+
parents.push(key) if deep_regexps
|
114
118
|
elsif blocks.any?
|
115
119
|
key = key.dup if key.duplicable?
|
116
120
|
value = value.dup if value.duplicable?
|
@@ -27,6 +27,10 @@ module ActiveSupport
|
|
27
27
|
@queue << o
|
28
28
|
end
|
29
29
|
|
30
|
+
def length
|
31
|
+
@queue.length
|
32
|
+
end
|
33
|
+
|
30
34
|
def pop; @queue.pop; end
|
31
35
|
end
|
32
36
|
|
@@ -90,8 +94,14 @@ module ActiveSupport
|
|
90
94
|
begin
|
91
95
|
queue.record(reporter, result)
|
92
96
|
rescue DRb::DRbConnError
|
93
|
-
result.failures.
|
94
|
-
failure.
|
97
|
+
result.failures.map! do |failure|
|
98
|
+
if failure.respond_to?(:error)
|
99
|
+
# minitest >5.14.0
|
100
|
+
error = DRb::DRbRemoteError.new(failure.error)
|
101
|
+
else
|
102
|
+
error = DRb::DRbRemoteError.new(failure.exception)
|
103
|
+
end
|
104
|
+
Minitest::UnexpectedError.new(error)
|
95
105
|
end
|
96
106
|
queue.record(reporter, result)
|
97
107
|
end
|
@@ -109,6 +119,10 @@ module ActiveSupport
|
|
109
119
|
def shutdown
|
110
120
|
@queue_size.times { @queue << nil }
|
111
121
|
@pool.each { |pid| Process.waitpid pid }
|
122
|
+
|
123
|
+
if @queue.length > 0
|
124
|
+
raise "Queue not empty, but all workers have finished. This probably means that a worker crashed and #{@queue.length} tests were missed."
|
125
|
+
end
|
112
126
|
end
|
113
127
|
|
114
128
|
private
|
@@ -40,7 +40,6 @@ module ActiveSupport
|
|
40
40
|
end
|
41
41
|
|
42
42
|
private
|
43
|
-
|
44
43
|
def unstub_object(stub)
|
45
44
|
singleton_class = stub.object.singleton_class
|
46
45
|
singleton_class.silence_redefinition_of_method stub.method_name
|
@@ -191,7 +190,6 @@ module ActiveSupport
|
|
191
190
|
end
|
192
191
|
|
193
192
|
private
|
194
|
-
|
195
193
|
def simple_stubs
|
196
194
|
@simple_stubs ||= SimpleStubs.new
|
197
195
|
end
|