activesupport 6.1.4.1 → 7.0.8.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +325 -395
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -2
- data/lib/active_support/actionable_error.rb +1 -1
- data/lib/active_support/array_inquirer.rb +0 -2
- data/lib/active_support/backtrace_cleaner.rb +2 -2
- data/lib/active_support/benchmarkable.rb +2 -2
- data/lib/active_support/cache/file_store.rb +15 -9
- data/lib/active_support/cache/mem_cache_store.rb +148 -37
- data/lib/active_support/cache/memory_store.rb +24 -16
- data/lib/active_support/cache/null_store.rb +10 -2
- data/lib/active_support/cache/redis_cache_store.rb +68 -85
- data/lib/active_support/cache/strategy/local_cache.rb +38 -61
- data/lib/active_support/cache.rb +299 -147
- data/lib/active_support/callbacks.rb +184 -85
- data/lib/active_support/code_generator.rb +65 -0
- data/lib/active_support/concern.rb +5 -5
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +2 -4
- data/lib/active_support/concurrency/share_lock.rb +2 -2
- data/lib/active_support/configurable.rb +8 -5
- data/lib/active_support/configuration_file.rb +1 -1
- data/lib/active_support/core_ext/array/access.rb +1 -5
- data/lib/active_support/core_ext/array/conversions.rb +13 -12
- data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
- data/lib/active_support/core_ext/array/grouping.rb +6 -6
- data/lib/active_support/core_ext/array/inquiry.rb +2 -2
- data/lib/active_support/core_ext/array.rb +1 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +1 -1
- data/lib/active_support/core_ext/class/subclasses.rb +25 -17
- data/lib/active_support/core_ext/date/blank.rb +1 -1
- data/lib/active_support/core_ext/date/calculations.rb +24 -9
- data/lib/active_support/core_ext/date/conversions.rb +14 -14
- data/lib/active_support/core_ext/date/deprecated_conversions.rb +40 -0
- data/lib/active_support/core_ext/date.rb +1 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +4 -4
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +1 -1
- data/lib/active_support/core_ext/date_time/blank.rb +1 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +4 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +13 -13
- data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +36 -0
- data/lib/active_support/core_ext/date_time.rb +1 -0
- data/lib/active_support/core_ext/digest/uuid.rb +39 -13
- data/lib/active_support/core_ext/enumerable.rb +112 -38
- data/lib/active_support/core_ext/file/atomic.rb +3 -1
- data/lib/active_support/core_ext/hash/conversions.rb +0 -1
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +3 -3
- data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
- data/lib/active_support/core_ext/hash/keys.rb +4 -4
- data/lib/active_support/core_ext/integer/inflections.rb +12 -12
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -4
- data/lib/active_support/core_ext/kernel/singleton_class.rb +1 -1
- data/lib/active_support/core_ext/module/attribute_accessors.rb +2 -0
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +19 -10
- data/lib/active_support/core_ext/module/delegation.rb +2 -8
- data/lib/active_support/core_ext/name_error.rb +2 -8
- data/lib/active_support/core_ext/numeric/conversions.rb +80 -77
- data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
- data/lib/active_support/core_ext/numeric.rb +1 -0
- data/lib/active_support/core_ext/object/acts_like.rb +29 -5
- data/lib/active_support/core_ext/object/blank.rb +2 -2
- data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
- data/lib/active_support/core_ext/object/duplicable.rb +15 -4
- data/lib/active_support/core_ext/object/json.rb +30 -25
- data/lib/active_support/core_ext/object/to_query.rb +2 -4
- data/lib/active_support/core_ext/object/try.rb +20 -20
- data/lib/active_support/core_ext/object/with_options.rb +21 -2
- data/lib/active_support/core_ext/pathname/existence.rb +21 -0
- data/lib/active_support/core_ext/pathname.rb +3 -0
- data/lib/active_support/core_ext/range/compare_range.rb +0 -25
- data/lib/active_support/core_ext/range/conversions.rb +8 -8
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +36 -0
- data/lib/active_support/core_ext/range/each.rb +1 -1
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +3 -26
- data/lib/active_support/core_ext/range/overlaps.rb +1 -1
- data/lib/active_support/core_ext/range.rb +1 -1
- data/lib/active_support/core_ext/securerandom.rb +1 -1
- data/lib/active_support/core_ext/string/conversions.rb +2 -2
- data/lib/active_support/core_ext/string/filters.rb +1 -1
- data/lib/active_support/core_ext/string/inflections.rb +1 -5
- data/lib/active_support/core_ext/string/inquiry.rb +1 -1
- data/lib/active_support/core_ext/string/output_safety.rb +94 -38
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +0 -8
- data/lib/active_support/core_ext/time/calculations.rb +13 -8
- data/lib/active_support/core_ext/time/conversions.rb +13 -12
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +73 -0
- data/lib/active_support/core_ext/time/zones.rb +10 -26
- data/lib/active_support/core_ext/time.rb +1 -0
- data/lib/active_support/core_ext/uri.rb +3 -27
- data/lib/active_support/core_ext.rb +1 -0
- data/lib/active_support/current_attributes.rb +31 -14
- data/lib/active_support/dependencies/interlock.rb +10 -18
- data/lib/active_support/dependencies/require_dependency.rb +28 -0
- data/lib/active_support/dependencies.rb +58 -788
- data/lib/active_support/deprecation/behaviors.rb +8 -5
- data/lib/active_support/deprecation/disallowed.rb +3 -3
- data/lib/active_support/deprecation/method_wrappers.rb +3 -3
- data/lib/active_support/deprecation/proxy_wrappers.rb +2 -2
- data/lib/active_support/deprecation.rb +2 -2
- data/lib/active_support/descendants_tracker.rb +174 -68
- data/lib/active_support/digest.rb +5 -3
- data/lib/active_support/duration/iso8601_parser.rb +3 -3
- data/lib/active_support/duration/iso8601_serializer.rb +9 -1
- data/lib/active_support/duration.rb +81 -51
- data/lib/active_support/encrypted_configuration.rb +45 -3
- data/lib/active_support/encrypted_file.rb +21 -10
- data/lib/active_support/environment_inquirer.rb +1 -1
- data/lib/active_support/error_reporter.rb +117 -0
- data/lib/active_support/evented_file_update_checker.rb +20 -7
- data/lib/active_support/execution_context/test_helper.rb +13 -0
- data/lib/active_support/execution_context.rb +53 -0
- data/lib/active_support/execution_wrapper.rb +43 -21
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/fork_tracker.rb +19 -12
- data/lib/active_support/gem_version.rb +5 -5
- data/lib/active_support/hash_with_indifferent_access.rb +3 -1
- data/lib/active_support/html_safe_translation.rb +43 -0
- data/lib/active_support/i18n.rb +1 -0
- data/lib/active_support/i18n_railtie.rb +1 -1
- data/lib/active_support/inflector/inflections.rb +23 -7
- data/lib/active_support/inflector/methods.rb +29 -55
- data/lib/active_support/inflector/transliterate.rb +1 -1
- data/lib/active_support/isolated_execution_state.rb +72 -0
- data/lib/active_support/json/encoding.rb +3 -3
- data/lib/active_support/key_generator.rb +22 -5
- data/lib/active_support/lazy_load_hooks.rb +28 -4
- data/lib/active_support/locale/en.yml +1 -1
- data/lib/active_support/log_subscriber/test_helper.rb +2 -2
- data/lib/active_support/log_subscriber.rb +15 -5
- data/lib/active_support/logger_thread_safe_level.rb +4 -13
- data/lib/active_support/message_encryptor.rb +12 -6
- data/lib/active_support/message_verifier.rb +46 -14
- data/lib/active_support/messages/metadata.rb +2 -2
- data/lib/active_support/multibyte/chars.rb +10 -11
- data/lib/active_support/multibyte/unicode.rb +0 -12
- data/lib/active_support/multibyte.rb +1 -1
- data/lib/active_support/notifications/fanout.rb +91 -65
- data/lib/active_support/notifications/instrumenter.rb +32 -15
- data/lib/active_support/notifications.rb +23 -23
- data/lib/active_support/number_helper/number_converter.rb +1 -3
- data/lib/active_support/number_helper/number_to_currency_converter.rb +11 -6
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -1
- data/lib/active_support/number_helper/rounding_helper.rb +1 -5
- data/lib/active_support/number_helper.rb +4 -5
- data/lib/active_support/option_merger.rb +10 -18
- data/lib/active_support/ordered_hash.rb +1 -1
- data/lib/active_support/ordered_options.rb +1 -1
- data/lib/active_support/parameter_filter.rb +20 -11
- data/lib/active_support/per_thread_registry.rb +5 -0
- data/lib/active_support/railtie.rb +69 -19
- data/lib/active_support/reloader.rb +1 -1
- data/lib/active_support/rescuable.rb +12 -12
- data/lib/active_support/ruby_features.rb +7 -0
- data/lib/active_support/secure_compare_rotator.rb +2 -2
- data/lib/active_support/string_inquirer.rb +0 -2
- data/lib/active_support/subscriber.rb +7 -18
- data/lib/active_support/tagged_logging.rb +2 -2
- data/lib/active_support/test_case.rb +13 -21
- data/lib/active_support/testing/assertions.rb +36 -6
- data/lib/active_support/testing/deprecation.rb +52 -1
- data/lib/active_support/testing/isolation.rb +30 -29
- data/lib/active_support/testing/method_call_assertions.rb +5 -5
- data/lib/active_support/testing/parallelization/server.rb +4 -0
- data/lib/active_support/testing/parallelization/worker.rb +3 -0
- data/lib/active_support/testing/parallelization.rb +4 -0
- data/lib/active_support/testing/parallelize_executor.rb +76 -0
- data/lib/active_support/testing/stream.rb +3 -5
- data/lib/active_support/testing/tagged_logging.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +13 -2
- data/lib/active_support/time_with_zone.rb +43 -22
- data/lib/active_support/values/time_zone.rb +35 -14
- data/lib/active_support/version.rb +1 -1
- data/lib/active_support/xml_mini/jdom.rb +1 -1
- data/lib/active_support/xml_mini/libxml.rb +5 -5
- data/lib/active_support/xml_mini/libxmlsax.rb +1 -1
- data/lib/active_support/xml_mini/nokogiri.rb +4 -4
- data/lib/active_support/xml_mini/nokogirisax.rb +1 -1
- data/lib/active_support/xml_mini/rexml.rb +1 -1
- data/lib/active_support/xml_mini.rb +5 -4
- data/lib/active_support.rb +17 -1
- metadata +26 -23
- data/lib/active_support/core_ext/marshal.rb +0 -26
- data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -117
@@ -3,27 +3,36 @@
|
|
3
3
|
require "active_support/core_ext/object/duplicable"
|
4
4
|
|
5
5
|
module ActiveSupport
|
6
|
-
# +ParameterFilter+
|
7
|
-
#
|
8
|
-
# sub-keys from a hash is possible by using the dot notation:
|
9
|
-
# 'credit_card.number'. If a proc is given, each key and value of a hash and
|
10
|
-
# all sub-hashes are passed to it, where the value or the key can be replaced
|
11
|
-
# using String#replace or similar methods.
|
6
|
+
# +ParameterFilter+ replaces values in a <tt>Hash</tt>-like object if their
|
7
|
+
# keys match one of the specified filters.
|
12
8
|
#
|
9
|
+
# Matching based on nested keys is possible by using dot notation, e.g.
|
10
|
+
# <tt>"credit_card.number"</tt>.
|
11
|
+
#
|
12
|
+
# If a proc is given as a filter, each key and value of the <tt>Hash</tt>-like
|
13
|
+
# and of any nested <tt>Hash</tt>es will be passed to it. The value or key can
|
14
|
+
# then be mutated as desired using methods such as <tt>String#replace</tt>.
|
15
|
+
#
|
16
|
+
# # Replaces values with "[FILTERED]" for keys that match /password/i.
|
13
17
|
# ActiveSupport::ParameterFilter.new([:password])
|
14
|
-
# => replaces the value to all keys matching /password/i with "[FILTERED]"
|
15
18
|
#
|
19
|
+
# # Replaces values with "[FILTERED]" for keys that match /foo|bar/i.
|
16
20
|
# ActiveSupport::ParameterFilter.new([:foo, "bar"])
|
17
|
-
# => replaces the value to all keys matching /foo|bar/i with "[FILTERED]"
|
18
21
|
#
|
22
|
+
# # Replaces values for the exact key "pin" and for keys that begin with
|
23
|
+
# # "pin_". Does not match keys that otherwise include "pin" as a
|
24
|
+
# # substring, such as "shipping_id".
|
25
|
+
# ActiveSupport::ParameterFilter.new([/\Apin\z/, /\Apin_/])
|
26
|
+
#
|
27
|
+
# # Replaces the value for :code in `{ credit_card: { code: "xxxx" } }`.
|
28
|
+
# # Does not change `{ file: { code: "xxxx" } }`.
|
19
29
|
# ActiveSupport::ParameterFilter.new(["credit_card.code"])
|
20
|
-
# => replaces { credit_card: {code: "xxxx"} } with "[FILTERED]", does not
|
21
|
-
# change { file: { code: "xxxx"} }
|
22
30
|
#
|
31
|
+
# # Reverses values for keys that match /secret/i.
|
23
32
|
# ActiveSupport::ParameterFilter.new([-> (k, v) do
|
24
33
|
# v.reverse! if /secret/i.match?(k)
|
25
34
|
# end])
|
26
|
-
#
|
35
|
+
#
|
27
36
|
class ParameterFilter
|
28
37
|
FILTERED = "[FILTERED]" # :nodoc:
|
29
38
|
|
@@ -40,6 +40,10 @@ module ActiveSupport
|
|
40
40
|
# If the class has an initializer, it must accept no arguments.
|
41
41
|
module PerThreadRegistry
|
42
42
|
def self.extended(object)
|
43
|
+
ActiveSupport::Deprecation.warn(<<~MSG)
|
44
|
+
ActiveSupport::PerThreadRegistry is deprecated and will be removed in Rails 7.1.
|
45
|
+
Use `Module#thread_mattr_accessor` instead.
|
46
|
+
MSG
|
43
47
|
object.instance_variable_set :@per_thread_registry_key, object.name.freeze
|
44
48
|
end
|
45
49
|
|
@@ -56,5 +60,6 @@ module ActiveSupport
|
|
56
60
|
|
57
61
|
send(name, *args, &block)
|
58
62
|
end
|
63
|
+
ruby2_keywords(:method_missing)
|
59
64
|
end
|
60
65
|
end
|
@@ -6,9 +6,27 @@ require "active_support/i18n_railtie"
|
|
6
6
|
module ActiveSupport
|
7
7
|
class Railtie < Rails::Railtie # :nodoc:
|
8
8
|
config.active_support = ActiveSupport::OrderedOptions.new
|
9
|
+
config.active_support.disable_to_s_conversion = false
|
9
10
|
|
10
11
|
config.eager_load_namespaces << ActiveSupport
|
11
12
|
|
13
|
+
initializer "active_support.isolation_level" do |app|
|
14
|
+
config.after_initialize do
|
15
|
+
if level = app.config.active_support.delete(:isolation_level)
|
16
|
+
ActiveSupport::IsolatedExecutionState.isolation_level = level
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
initializer "active_support.remove_deprecated_time_with_zone_name" do |app|
|
22
|
+
config.after_initialize do
|
23
|
+
if app.config.active_support.remove_deprecated_time_with_zone_name
|
24
|
+
require "active_support/time_with_zone"
|
25
|
+
TimeWithZone.singleton_class.remove_method(:name)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
12
30
|
initializer "active_support.set_authenticated_message_encryption" do |app|
|
13
31
|
config.after_initialize do
|
14
32
|
unless app.config.active_support.use_authenticated_message_encryption.nil?
|
@@ -18,28 +36,48 @@ module ActiveSupport
|
|
18
36
|
end
|
19
37
|
end
|
20
38
|
|
39
|
+
initializer "active_support.reset_execution_context" do |app|
|
40
|
+
app.reloader.before_class_unload { ActiveSupport::ExecutionContext.clear }
|
41
|
+
app.executor.to_run { ActiveSupport::ExecutionContext.clear }
|
42
|
+
app.executor.to_complete { ActiveSupport::ExecutionContext.clear }
|
43
|
+
end
|
44
|
+
|
21
45
|
initializer "active_support.reset_all_current_attributes_instances" do |app|
|
22
46
|
app.reloader.before_class_unload { ActiveSupport::CurrentAttributes.clear_all }
|
23
47
|
app.executor.to_run { ActiveSupport::CurrentAttributes.reset_all }
|
24
48
|
app.executor.to_complete { ActiveSupport::CurrentAttributes.reset_all }
|
25
49
|
|
26
50
|
ActiveSupport.on_load(:active_support_test_case) do
|
27
|
-
|
28
|
-
|
51
|
+
if app.config.active_support.executor_around_test_case
|
52
|
+
require "active_support/executor/test_helper"
|
53
|
+
include ActiveSupport::Executor::TestHelper
|
54
|
+
else
|
55
|
+
require "active_support/current_attributes/test_helper"
|
56
|
+
include ActiveSupport::CurrentAttributes::TestHelper
|
57
|
+
|
58
|
+
require "active_support/execution_context/test_helper"
|
59
|
+
include ActiveSupport::ExecutionContext::TestHelper
|
60
|
+
end
|
29
61
|
end
|
30
62
|
end
|
31
63
|
|
32
64
|
initializer "active_support.deprecation_behavior" do |app|
|
33
|
-
if
|
34
|
-
ActiveSupport::Deprecation.
|
35
|
-
|
65
|
+
if app.config.active_support.report_deprecations == false
|
66
|
+
ActiveSupport::Deprecation.silenced = true
|
67
|
+
ActiveSupport::Deprecation.behavior = :silence
|
68
|
+
ActiveSupport::Deprecation.disallowed_behavior = :silence
|
69
|
+
else
|
70
|
+
if deprecation = app.config.active_support.deprecation
|
71
|
+
ActiveSupport::Deprecation.behavior = deprecation
|
72
|
+
end
|
36
73
|
|
37
|
-
|
38
|
-
|
39
|
-
|
74
|
+
if disallowed_deprecation = app.config.active_support.disallowed_deprecation
|
75
|
+
ActiveSupport::Deprecation.disallowed_behavior = disallowed_deprecation
|
76
|
+
end
|
40
77
|
|
41
|
-
|
42
|
-
|
78
|
+
if disallowed_warnings = app.config.active_support.disallowed_deprecation_warnings
|
79
|
+
ActiveSupport::Deprecation.disallowed_warnings = disallowed_warnings
|
80
|
+
end
|
43
81
|
end
|
44
82
|
end
|
45
83
|
|
@@ -75,6 +113,10 @@ module ActiveSupport
|
|
75
113
|
end
|
76
114
|
end
|
77
115
|
|
116
|
+
initializer "active_support.set_error_reporter" do |app|
|
117
|
+
ActiveSupport.error_reporter = app.executor.error_reporter
|
118
|
+
end
|
119
|
+
|
78
120
|
initializer "active_support.set_configs" do |app|
|
79
121
|
app.config.active_support.each do |k, v|
|
80
122
|
k = "#{k}="
|
@@ -84,19 +126,27 @@ module ActiveSupport
|
|
84
126
|
|
85
127
|
initializer "active_support.set_hash_digest_class" do |app|
|
86
128
|
config.after_initialize do
|
87
|
-
if app.config.active_support.use_sha1_digests
|
88
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
89
|
-
config.active_support.use_sha1_digests is deprecated and will
|
90
|
-
be removed from Rails 6.2. Use
|
91
|
-
config.active_support.hash_digest_class = ::Digest::SHA1 instead.
|
92
|
-
MSG
|
93
|
-
ActiveSupport::Digest.hash_digest_class = ::Digest::SHA1
|
94
|
-
end
|
95
|
-
|
96
129
|
if klass = app.config.active_support.hash_digest_class
|
97
130
|
ActiveSupport::Digest.hash_digest_class = klass
|
98
131
|
end
|
99
132
|
end
|
100
133
|
end
|
134
|
+
|
135
|
+
initializer "active_support.set_key_generator_hash_digest_class" do |app|
|
136
|
+
config.after_initialize do
|
137
|
+
if klass = app.config.active_support.key_generator_hash_digest_class
|
138
|
+
ActiveSupport::KeyGenerator.hash_digest_class = klass
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
initializer "active_support.set_rfc4122_namespaced_uuids" do |app|
|
144
|
+
config.after_initialize do
|
145
|
+
if app.config.active_support.use_rfc4122_namespaced_uuids
|
146
|
+
require "active_support/core_ext/digest"
|
147
|
+
::Digest::UUID.use_rfc4122_namespaced_uuids = app.config.active_support.use_rfc4122_namespaced_uuids
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
101
151
|
end
|
102
152
|
end
|
@@ -30,20 +30,20 @@ module ActiveSupport
|
|
30
30
|
# any.
|
31
31
|
#
|
32
32
|
# class ApplicationController < ActionController::Base
|
33
|
-
# rescue_from User::NotAuthorized, with: :deny_access
|
34
|
-
# rescue_from ActiveRecord::RecordInvalid, with: :
|
33
|
+
# rescue_from User::NotAuthorized, with: :deny_access
|
34
|
+
# rescue_from ActiveRecord::RecordInvalid, with: :show_record_errors
|
35
35
|
#
|
36
|
-
# rescue_from
|
37
|
-
#
|
36
|
+
# rescue_from "MyApp::BaseError" do |exception|
|
37
|
+
# redirect_to root_url, alert: exception.message
|
38
38
|
# end
|
39
39
|
#
|
40
40
|
# private
|
41
41
|
# def deny_access
|
42
|
-
#
|
42
|
+
# head :forbidden
|
43
43
|
# end
|
44
44
|
#
|
45
|
-
# def
|
46
|
-
# exception.record.
|
45
|
+
# def show_record_errors(exception)
|
46
|
+
# redirect_back_or_to root_url, alert: exception.record.errors.full_messages.to_sentence
|
47
47
|
# end
|
48
48
|
# end
|
49
49
|
#
|
@@ -74,12 +74,12 @@ module ActiveSupport
|
|
74
74
|
# Matches an exception to a handler based on the exception class.
|
75
75
|
#
|
76
76
|
# If no handler matches the exception, check for a handler matching the
|
77
|
-
# (optional) exception.cause
|
77
|
+
# (optional) +exception.cause+. If no handler matches the exception or its
|
78
78
|
# cause, this returns +nil+, so you can deal with unhandled exceptions.
|
79
79
|
# Be sure to re-raise unhandled exceptions if this is what you expect.
|
80
80
|
#
|
81
81
|
# begin
|
82
|
-
#
|
82
|
+
# # ...
|
83
83
|
# rescue => exception
|
84
84
|
# rescue_with_handler(exception) || raise
|
85
85
|
# end
|
@@ -100,7 +100,7 @@ module ActiveSupport
|
|
100
100
|
end
|
101
101
|
end
|
102
102
|
|
103
|
-
def handler_for_rescue(exception, object: self)
|
103
|
+
def handler_for_rescue(exception, object: self) # :nodoc:
|
104
104
|
case rescuer = find_rescue_handler(exception)
|
105
105
|
when Symbol
|
106
106
|
method = object.method(rescuer)
|
@@ -160,14 +160,14 @@ module ActiveSupport
|
|
160
160
|
end
|
161
161
|
|
162
162
|
# Delegates to the class method, but uses the instance as the subject for
|
163
|
-
# rescue_from handlers (method calls, instance_exec blocks).
|
163
|
+
# rescue_from handlers (method calls, +instance_exec+ blocks).
|
164
164
|
def rescue_with_handler(exception)
|
165
165
|
self.class.rescue_with_handler exception, object: self
|
166
166
|
end
|
167
167
|
|
168
168
|
# Internal handler lookup. Delegates to class method. Some libraries call
|
169
169
|
# this directly, so keeping it around for compatibility.
|
170
|
-
def handler_for_rescue(exception)
|
170
|
+
def handler_for_rescue(exception) # :nodoc:
|
171
171
|
self.class.handler_for_rescue exception, object: self
|
172
172
|
end
|
173
173
|
end
|
@@ -4,7 +4,7 @@ require "active_support/security_utils"
|
|
4
4
|
require "active_support/messages/rotator"
|
5
5
|
|
6
6
|
module ActiveSupport
|
7
|
-
# The ActiveSupport::SecureCompareRotator is a wrapper around
|
7
|
+
# The ActiveSupport::SecureCompareRotator is a wrapper around ActiveSupport::SecurityUtils.secure_compare
|
8
8
|
# and allows you to rotate a previously defined value to a new one.
|
9
9
|
#
|
10
10
|
# It can be used as follow:
|
@@ -17,7 +17,7 @@ module ActiveSupport
|
|
17
17
|
#
|
18
18
|
# class MyController < ApplicationController
|
19
19
|
# def authenticate_request
|
20
|
-
# rotator = ActiveSupport::
|
20
|
+
# rotator = ActiveSupport::SecureCompareRotator.new('new_password')
|
21
21
|
# rotator.rotate('old_password')
|
22
22
|
#
|
23
23
|
# authenticate_or_request_with_http_basic do |username, password|
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_support/per_thread_registry"
|
4
3
|
require "active_support/notifications"
|
5
4
|
|
6
5
|
module ActiveSupport
|
@@ -150,25 +149,15 @@ module ActiveSupport
|
|
150
149
|
send(method, event)
|
151
150
|
end
|
152
151
|
|
152
|
+
def publish_event(event) # :nodoc:
|
153
|
+
method = event.name.split(".").first
|
154
|
+
send(method, event)
|
155
|
+
end
|
156
|
+
|
153
157
|
private
|
154
158
|
def event_stack
|
155
|
-
|
159
|
+
registry = ActiveSupport::IsolatedExecutionState[:active_support_subscriber_queue_registry] ||= {}
|
160
|
+
registry[@queue_key] ||= []
|
156
161
|
end
|
157
162
|
end
|
158
|
-
|
159
|
-
# This is a registry for all the event stacks kept for subscribers.
|
160
|
-
#
|
161
|
-
# See the documentation of <tt>ActiveSupport::PerThreadRegistry</tt>
|
162
|
-
# for further details.
|
163
|
-
class SubscriberQueueRegistry # :nodoc:
|
164
|
-
extend PerThreadRegistry
|
165
|
-
|
166
|
-
def initialize
|
167
|
-
@registry = {}
|
168
|
-
end
|
169
|
-
|
170
|
-
def get_queue(queue_key)
|
171
|
-
@registry[queue_key] ||= []
|
172
|
-
end
|
173
|
-
end
|
174
163
|
end
|
@@ -57,7 +57,7 @@ module ActiveSupport
|
|
57
57
|
def current_tags
|
58
58
|
# We use our object ID here to avoid conflicting with other instances
|
59
59
|
thread_key = @thread_key ||= "activesupport_tagged_logging_tags:#{object_id}"
|
60
|
-
|
60
|
+
IsolatedExecutionState[thread_key] ||= []
|
61
61
|
end
|
62
62
|
|
63
63
|
def tags_text
|
@@ -79,7 +79,7 @@ module ActiveSupport
|
|
79
79
|
end
|
80
80
|
|
81
81
|
def self.new(logger)
|
82
|
-
logger = logger.
|
82
|
+
logger = logger.clone
|
83
83
|
|
84
84
|
if logger.formatter
|
85
85
|
logger.formatter = logger.formatter.dup
|
@@ -12,6 +12,7 @@ require "active_support/testing/constant_lookup"
|
|
12
12
|
require "active_support/testing/time_helpers"
|
13
13
|
require "active_support/testing/file_fixtures"
|
14
14
|
require "active_support/testing/parallelization"
|
15
|
+
require "active_support/testing/parallelize_executor"
|
15
16
|
require "concurrent/utility/processor_counter"
|
16
17
|
|
17
18
|
module ActiveSupport
|
@@ -71,26 +72,17 @@ module ActiveSupport
|
|
71
72
|
#
|
72
73
|
# The threaded parallelization uses minitest's parallel executor directly.
|
73
74
|
# The processes parallelization uses a Ruby DRb server.
|
74
|
-
|
75
|
+
#
|
76
|
+
# Because parallelization presents an overhead, it is only enabled when the
|
77
|
+
# number of tests to run is above the +threshold+ param. The default value is
|
78
|
+
# 50, and it's configurable via +config.active_support.test_parallelization_threshold+.
|
79
|
+
def parallelize(workers: :number_of_processors, with: :processes, threshold: ActiveSupport.test_parallelization_threshold)
|
75
80
|
workers = Concurrent.physical_processor_count if workers == :number_of_processors
|
76
81
|
workers = ENV["PARALLEL_WORKERS"].to_i if ENV["PARALLEL_WORKERS"]
|
77
82
|
|
78
83
|
return if workers <= 1
|
79
84
|
|
80
|
-
|
81
|
-
when :processes
|
82
|
-
Testing::Parallelization.new(workers)
|
83
|
-
when :threads
|
84
|
-
Minitest::Parallel::Executor.new(workers)
|
85
|
-
else
|
86
|
-
raise ArgumentError, "#{with} is not a supported parallelization executor."
|
87
|
-
end
|
88
|
-
|
89
|
-
self.lock_threads = false if defined?(self.lock_threads) && with == :threads
|
90
|
-
|
91
|
-
Minitest.parallel_executor = executor
|
92
|
-
|
93
|
-
parallelize_me!
|
85
|
+
Minitest.parallel_executor = ActiveSupport::Testing::ParallelizeExecutor.new(size: workers, with: with, threshold: threshold)
|
94
86
|
end
|
95
87
|
|
96
88
|
# Set up hook for parallel testing. This can be used if you have multiple
|
@@ -107,9 +99,7 @@ module ActiveSupport
|
|
107
99
|
# end
|
108
100
|
# end
|
109
101
|
def parallelize_setup(&block)
|
110
|
-
ActiveSupport::Testing::Parallelization.after_fork_hook
|
111
|
-
yield worker
|
112
|
-
end
|
102
|
+
ActiveSupport::Testing::Parallelization.after_fork_hook(&block)
|
113
103
|
end
|
114
104
|
|
115
105
|
# Clean up hook for parallel testing. This can be used to drop databases
|
@@ -126,9 +116,7 @@ module ActiveSupport
|
|
126
116
|
# end
|
127
117
|
# end
|
128
118
|
def parallelize_teardown(&block)
|
129
|
-
ActiveSupport::Testing::Parallelization.run_cleanup_hook
|
130
|
-
yield worker
|
131
|
-
end
|
119
|
+
ActiveSupport::Testing::Parallelization.run_cleanup_hook(&block)
|
132
120
|
end
|
133
121
|
end
|
134
122
|
|
@@ -159,5 +147,9 @@ module ActiveSupport
|
|
159
147
|
alias :assert_not_same :refute_same
|
160
148
|
|
161
149
|
ActiveSupport.run_load_hooks(:active_support_test_case, self)
|
150
|
+
|
151
|
+
def inspect # :nodoc:
|
152
|
+
Object.instance_method(:to_s).bind_call(self)
|
153
|
+
end
|
162
154
|
end
|
163
155
|
end
|
@@ -99,7 +99,7 @@ module ActiveSupport
|
|
99
99
|
}
|
100
100
|
before = exps.map(&:call)
|
101
101
|
|
102
|
-
retval =
|
102
|
+
retval = _assert_nothing_raised_or_warn("assert_difference", &block)
|
103
103
|
|
104
104
|
expressions.zip(exps, before) do |(code, diff), exp, before_value|
|
105
105
|
error = "#{code.inspect} didn't change by #{diff}"
|
@@ -159,7 +159,7 @@ module ActiveSupport
|
|
159
159
|
# @object = 42
|
160
160
|
# end
|
161
161
|
#
|
162
|
-
# The keyword arguments
|
162
|
+
# The keyword arguments +:from+ and +:to+ can be given to specify the
|
163
163
|
# expected initial value and the expected value after the block was
|
164
164
|
# executed.
|
165
165
|
#
|
@@ -176,7 +176,7 @@ module ActiveSupport
|
|
176
176
|
exp = expression.respond_to?(:call) ? expression : -> { eval(expression.to_s, block.binding) }
|
177
177
|
|
178
178
|
before = exp.call
|
179
|
-
retval =
|
179
|
+
retval = _assert_nothing_raised_or_warn("assert_changes", &block)
|
180
180
|
|
181
181
|
unless from == UNTRACKED
|
182
182
|
error = "Expected change from #{from.inspect}"
|
@@ -189,7 +189,7 @@ module ActiveSupport
|
|
189
189
|
error = "#{expression.inspect} didn't change"
|
190
190
|
error = "#{error}. It was already #{to}" if before == to
|
191
191
|
error = "#{message}.\n#{error}" if message
|
192
|
-
|
192
|
+
refute_equal before, after, error
|
193
193
|
|
194
194
|
unless to == UNTRACKED
|
195
195
|
error = "Expected change to #{to}\n"
|
@@ -207,16 +207,30 @@ module ActiveSupport
|
|
207
207
|
# post :create, params: { status: { ok: true } }
|
208
208
|
# end
|
209
209
|
#
|
210
|
+
# Provide the optional keyword argument :from to specify the expected
|
211
|
+
# initial value.
|
212
|
+
#
|
213
|
+
# assert_no_changes -> { Status.all_good? }, from: true do
|
214
|
+
# post :create, params: { status: { ok: true } }
|
215
|
+
# end
|
216
|
+
#
|
210
217
|
# An error message can be specified.
|
211
218
|
#
|
212
219
|
# assert_no_changes -> { Status.all_good? }, 'Expected the status to be good' do
|
213
220
|
# post :create, params: { status: { ok: false } }
|
214
221
|
# end
|
215
|
-
def assert_no_changes(expression, message = nil, &block)
|
222
|
+
def assert_no_changes(expression, message = nil, from: UNTRACKED, &block)
|
216
223
|
exp = expression.respond_to?(:call) ? expression : -> { eval(expression.to_s, block.binding) }
|
217
224
|
|
218
225
|
before = exp.call
|
219
|
-
retval =
|
226
|
+
retval = _assert_nothing_raised_or_warn("assert_no_changes", &block)
|
227
|
+
|
228
|
+
unless from == UNTRACKED
|
229
|
+
error = "Expected initial value of #{from.inspect}"
|
230
|
+
error = "#{message}.\n#{error}" if message
|
231
|
+
assert from === before, error
|
232
|
+
end
|
233
|
+
|
220
234
|
after = exp.call
|
221
235
|
|
222
236
|
error = "#{expression.inspect} changed"
|
@@ -230,6 +244,22 @@ module ActiveSupport
|
|
230
244
|
|
231
245
|
retval
|
232
246
|
end
|
247
|
+
|
248
|
+
private
|
249
|
+
def _assert_nothing_raised_or_warn(assertion, &block)
|
250
|
+
assert_nothing_raised(&block)
|
251
|
+
rescue Minitest::UnexpectedError => e
|
252
|
+
if tagged_logger && tagged_logger.warn?
|
253
|
+
warning = <<~MSG
|
254
|
+
#{self.class} - #{name}: #{e.error.class} raised.
|
255
|
+
If you expected this exception, use `assert_raises` as near to the code that raises as possible.
|
256
|
+
Other block based assertions (e.g. `#{assertion}`) can be used, as long as `assert_raises` is inside their block.
|
257
|
+
MSG
|
258
|
+
tagged_logger.warn warning
|
259
|
+
end
|
260
|
+
|
261
|
+
raise
|
262
|
+
end
|
233
263
|
end
|
234
264
|
end
|
235
265
|
end
|
@@ -4,7 +4,30 @@ require "active_support/deprecation"
|
|
4
4
|
|
5
5
|
module ActiveSupport
|
6
6
|
module Testing
|
7
|
-
module Deprecation
|
7
|
+
module Deprecation
|
8
|
+
# Asserts that a matching deprecation warning was emitted by the given deprecator during the execution of the yielded block.
|
9
|
+
#
|
10
|
+
# assert_deprecated(/foo/, CustomDeprecator) do
|
11
|
+
# CustomDeprecator.warn "foo should no longer be used"
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# The +match+ object may be a +Regexp+, or +String+ appearing in the message.
|
15
|
+
#
|
16
|
+
# assert_deprecated('foo', CustomDeprecator) do
|
17
|
+
# CustomDeprecator.warn "foo should no longer be used"
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# If the +match+ is omitted (or explicitly +nil+), any deprecation warning will match.
|
21
|
+
#
|
22
|
+
# assert_deprecated(nil, CustomDeprecator) do
|
23
|
+
# CustomDeprecator.warn "foo should no longer be used"
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# If no +deprecator+ is given, defaults to ActiveSupport::Deprecation.
|
27
|
+
#
|
28
|
+
# assert_deprecated do
|
29
|
+
# ActiveSupport::Deprecation.warn "foo should no longer be used"
|
30
|
+
# end
|
8
31
|
def assert_deprecated(match = nil, deprecator = nil, &block)
|
9
32
|
result, warnings = collect_deprecations(deprecator, &block)
|
10
33
|
assert !warnings.empty?, "Expected a deprecation warning within the block but received none"
|
@@ -15,12 +38,40 @@ module ActiveSupport
|
|
15
38
|
result
|
16
39
|
end
|
17
40
|
|
41
|
+
# Asserts that no deprecation warnings are emitted by the given deprecator during the execution of the yielded block.
|
42
|
+
#
|
43
|
+
# assert_not_deprecated(CustomDeprecator) do
|
44
|
+
# CustomDeprecator.warn "message" # fails assertion
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# If no +deprecator+ is given, defaults to ActiveSupport::Deprecation.
|
48
|
+
#
|
49
|
+
# assert_not_deprecated do
|
50
|
+
# ActiveSupport::Deprecation.warn "message" # fails assertion
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
# assert_not_deprecated do
|
54
|
+
# CustomDeprecator.warn "message" # passes assertion
|
55
|
+
# end
|
18
56
|
def assert_not_deprecated(deprecator = nil, &block)
|
19
57
|
result, deprecations = collect_deprecations(deprecator, &block)
|
20
58
|
assert deprecations.empty?, "Expected no deprecation warning within the block but received #{deprecations.size}: \n #{deprecations * "\n "}"
|
21
59
|
result
|
22
60
|
end
|
23
61
|
|
62
|
+
# Returns an array of all the deprecation warnings emitted by the given
|
63
|
+
# +deprecator+ during the execution of the yielded block.
|
64
|
+
#
|
65
|
+
# collect_deprecations(CustomDeprecator) do
|
66
|
+
# CustomDeprecator.warn "message"
|
67
|
+
# end # => ["message"]
|
68
|
+
#
|
69
|
+
# If no +deprecator+ is given, defaults to ActiveSupport::Deprecation.
|
70
|
+
#
|
71
|
+
# collect_deprecations do
|
72
|
+
# CustomDeprecator.warn "custom message"
|
73
|
+
# ActiveSupport::Deprecation.warn "message"
|
74
|
+
# end # => ["message"]
|
24
75
|
def collect_deprecations(deprecator = nil)
|
25
76
|
deprecator ||= ActiveSupport::Deprecation
|
26
77
|
old_behavior = deprecator.behavior
|