activesupport 7.0.3.1 → 7.2.3.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 +261 -246
- data/MIT-LICENSE +1 -1
- data/README.rdoc +7 -7
- data/lib/active_support/actionable_error.rb +3 -1
- data/lib/active_support/array_inquirer.rb +3 -1
- data/lib/active_support/backtrace_cleaner.rb +39 -7
- data/lib/active_support/benchmarkable.rb +1 -0
- data/lib/active_support/broadcast_logger.rb +238 -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 +51 -19
- data/lib/active_support/cache/mem_cache_store.rb +114 -134
- data/lib/active_support/cache/memory_store.rb +85 -30
- data/lib/active_support/cache/null_store.rb +8 -2
- data/lib/active_support/cache/redis_cache_store.rb +175 -154
- data/lib/active_support/cache/serializer_with_fallback.rb +152 -0
- data/lib/active_support/cache/strategy/local_cache.rb +64 -13
- data/lib/active_support/cache.rb +455 -378
- data/lib/active_support/callbacks.rb +121 -136
- data/lib/active_support/code_generator.rb +15 -10
- data/lib/active_support/concern.rb +4 -2
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +42 -3
- data/lib/active_support/concurrency/null_lock.rb +13 -0
- data/lib/active_support/configurable.rb +10 -0
- data/lib/active_support/core_ext/array/conversions.rb +1 -2
- data/lib/active_support/core_ext/array.rb +0 -1
- data/lib/active_support/core_ext/benchmark.rb +1 -0
- data/lib/active_support/core_ext/class/attribute.rb +2 -2
- data/lib/active_support/core_ext/class/subclasses.rb +17 -34
- data/lib/active_support/core_ext/date/blank.rb +4 -0
- data/lib/active_support/core_ext/date/calculations.rb +15 -0
- data/lib/active_support/core_ext/date/conversions.rb +1 -2
- data/lib/active_support/core_ext/date.rb +0 -1
- data/lib/active_support/core_ext/date_and_time/calculations.rb +10 -0
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +28 -1
- data/lib/active_support/core_ext/date_time/blank.rb +4 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +4 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +6 -4
- data/lib/active_support/core_ext/date_time.rb +0 -1
- data/lib/active_support/core_ext/digest/uuid.rb +7 -10
- data/lib/active_support/core_ext/enumerable.rb +25 -80
- data/lib/active_support/core_ext/erb/util.rb +201 -0
- data/lib/active_support/core_ext/hash/conversions.rb +1 -1
- 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/keys.rb +7 -7
- data/lib/active_support/core_ext/integer/inflections.rb +12 -12
- data/lib/active_support/core_ext/module/attr_internal.rb +17 -6
- data/lib/active_support/core_ext/module/attribute_accessors.rb +6 -0
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +34 -16
- data/lib/active_support/core_ext/module/concerning.rb +6 -6
- data/lib/active_support/core_ext/module/delegation.rb +20 -119
- data/lib/active_support/core_ext/module/deprecation.rb +12 -12
- data/lib/active_support/core_ext/module/introspection.rb +3 -1
- data/lib/active_support/core_ext/numeric/bytes.rb +9 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +5 -3
- data/lib/active_support/core_ext/numeric.rb +0 -1
- data/lib/active_support/core_ext/object/blank.rb +45 -1
- data/lib/active_support/core_ext/object/deep_dup.rb +16 -0
- data/lib/active_support/core_ext/object/duplicable.rb +25 -16
- data/lib/active_support/core_ext/object/inclusion.rb +13 -5
- data/lib/active_support/core_ext/object/instance_variables.rb +4 -2
- data/lib/active_support/core_ext/object/json.rb +17 -7
- data/lib/active_support/core_ext/object/to_query.rb +0 -2
- data/lib/active_support/core_ext/object/try.rb +2 -2
- data/lib/active_support/core_ext/object/with.rb +46 -0
- data/lib/active_support/core_ext/object/with_options.rb +9 -9
- data/lib/active_support/core_ext/object.rb +1 -0
- data/lib/active_support/core_ext/pathname/blank.rb +20 -0
- data/lib/active_support/core_ext/pathname/existence.rb +2 -0
- data/lib/active_support/core_ext/pathname.rb +1 -0
- data/lib/active_support/core_ext/range/conversions.rb +28 -7
- data/lib/active_support/core_ext/range/overlap.rb +40 -0
- data/lib/active_support/core_ext/range/sole.rb +17 -0
- data/lib/active_support/core_ext/range.rb +2 -2
- data/lib/active_support/core_ext/securerandom.rb +24 -12
- data/lib/active_support/core_ext/string/conversions.rb +1 -1
- data/lib/active_support/core_ext/string/filters.rb +24 -18
- data/lib/active_support/core_ext/string/indent.rb +1 -1
- data/lib/active_support/core_ext/string/inflections.rb +16 -9
- data/lib/active_support/core_ext/string/multibyte.rb +3 -3
- data/lib/active_support/core_ext/string/output_safety.rb +41 -178
- data/lib/active_support/core_ext/thread/backtrace/location.rb +12 -0
- data/lib/active_support/core_ext/time/calculations.rb +40 -30
- data/lib/active_support/core_ext/time/compatibility.rb +24 -0
- data/lib/active_support/core_ext/time/conversions.rb +1 -3
- data/lib/active_support/core_ext/time/zones.rb +7 -8
- data/lib/active_support/core_ext/time.rb +0 -1
- data/lib/active_support/core_ext.rb +0 -1
- data/lib/active_support/current_attributes.rb +60 -46
- data/lib/active_support/deep_mergeable.rb +53 -0
- data/lib/active_support/delegation.rb +202 -0
- data/lib/active_support/dependencies/autoload.rb +9 -16
- data/lib/active_support/deprecation/behaviors.rb +64 -41
- data/lib/active_support/deprecation/constant_accessor.rb +47 -25
- data/lib/active_support/deprecation/deprecators.rb +104 -0
- data/lib/active_support/deprecation/disallowed.rb +6 -8
- data/lib/active_support/deprecation/method_wrappers.rb +6 -23
- data/lib/active_support/deprecation/proxy_wrappers.rb +34 -22
- data/lib/active_support/deprecation/reporting.rb +49 -27
- data/lib/active_support/deprecation.rb +39 -9
- data/lib/active_support/deprecator.rb +7 -0
- data/lib/active_support/descendants_tracker.rb +66 -172
- data/lib/active_support/duration/iso8601_parser.rb +2 -2
- data/lib/active_support/duration/iso8601_serializer.rb +1 -4
- data/lib/active_support/duration.rb +13 -7
- data/lib/active_support/encrypted_configuration.rb +63 -11
- data/lib/active_support/encrypted_file.rb +29 -13
- data/lib/active_support/environment_inquirer.rb +22 -2
- data/lib/active_support/error_reporter/test_helper.rb +15 -0
- data/lib/active_support/error_reporter.rb +163 -36
- data/lib/active_support/evented_file_update_checker.rb +17 -3
- data/lib/active_support/execution_wrapper.rb +5 -6
- data/lib/active_support/file_update_checker.rb +6 -4
- data/lib/active_support/fork_tracker.rb +4 -32
- data/lib/active_support/gem_version.rb +2 -2
- data/lib/active_support/gzip.rb +2 -0
- data/lib/active_support/hash_with_indifferent_access.rb +50 -30
- data/lib/active_support/html_safe_translation.rb +19 -6
- data/lib/active_support/i18n.rb +1 -1
- data/lib/active_support/i18n_railtie.rb +20 -13
- data/lib/active_support/inflector/inflections.rb +2 -0
- data/lib/active_support/inflector/methods.rb +28 -18
- data/lib/active_support/inflector/transliterate.rb +3 -1
- data/lib/active_support/isolated_execution_state.rb +26 -22
- data/lib/active_support/json/decoding.rb +3 -2
- data/lib/active_support/json/encoding.rb +48 -48
- data/lib/active_support/key_generator.rb +9 -1
- data/lib/active_support/lazy_load_hooks.rb +22 -7
- data/lib/active_support/locale/en.yml +2 -0
- data/lib/active_support/log_subscriber.rb +74 -34
- data/lib/active_support/logger.rb +22 -59
- data/lib/active_support/logger_thread_safe_level.rb +10 -32
- data/lib/active_support/message_encryptor.rb +197 -53
- 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 +305 -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 +229 -89
- data/lib/active_support/message_verifiers.rb +137 -0
- data/lib/active_support/messages/codec.rb +65 -0
- data/lib/active_support/messages/metadata.rb +111 -45
- data/lib/active_support/messages/rotation_coordinator.rb +93 -0
- data/lib/active_support/messages/rotator.rb +38 -31
- data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
- data/lib/active_support/multibyte/chars.rb +8 -3
- data/lib/active_support/multibyte/unicode.rb +9 -37
- data/lib/active_support/notifications/fanout.rb +248 -87
- data/lib/active_support/notifications/instrumenter.rb +93 -25
- data/lib/active_support/notifications.rb +36 -29
- data/lib/active_support/number_helper/number_converter.rb +16 -7
- data/lib/active_support/number_helper/number_to_currency_converter.rb +6 -6
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +17 -2
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +3 -3
- data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -0
- data/lib/active_support/number_helper.rb +379 -317
- data/lib/active_support/option_merger.rb +4 -4
- data/lib/active_support/ordered_hash.rb +3 -3
- data/lib/active_support/ordered_options.rb +67 -15
- data/lib/active_support/parameter_filter.rb +103 -84
- data/lib/active_support/proxy_object.rb +8 -3
- data/lib/active_support/railtie.rb +25 -20
- data/lib/active_support/reloader.rb +12 -4
- data/lib/active_support/rescuable.rb +10 -8
- data/lib/active_support/secure_compare_rotator.rb +16 -9
- data/lib/active_support/string_inquirer.rb +4 -2
- data/lib/active_support/subscriber.rb +10 -27
- data/lib/active_support/syntax_error_proxy.rb +60 -0
- data/lib/active_support/tagged_logging.rb +64 -40
- data/lib/active_support/test_case.rb +160 -7
- data/lib/active_support/testing/assertions.rb +28 -12
- data/lib/active_support/testing/autorun.rb +0 -2
- data/lib/active_support/testing/constant_stubbing.rb +54 -0
- data/lib/active_support/testing/deprecation.rb +20 -27
- data/lib/active_support/testing/error_reporter_assertions.rb +107 -0
- data/lib/active_support/testing/isolation.rb +46 -33
- data/lib/active_support/testing/method_call_assertions.rb +7 -8
- data/lib/active_support/testing/parallelization/server.rb +18 -2
- data/lib/active_support/testing/parallelization/worker.rb +2 -2
- data/lib/active_support/testing/parallelization.rb +12 -1
- data/lib/active_support/testing/parallelize_executor.rb +8 -3
- data/lib/active_support/testing/setup_and_teardown.rb +2 -0
- data/lib/active_support/testing/stream.rb +1 -1
- data/lib/active_support/testing/tests_without_assertions.rb +19 -0
- data/lib/active_support/testing/time_helpers.rb +38 -16
- data/lib/active_support/time_with_zone.rb +18 -44
- data/lib/active_support/values/time_zone.rb +25 -14
- data/lib/active_support/version.rb +1 -1
- data/lib/active_support/xml_mini/jdom.rb +3 -10
- data/lib/active_support/xml_mini/nokogiri.rb +1 -1
- 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 +14 -3
- data/lib/active_support.rb +15 -3
- metadata +148 -24
- data/lib/active_support/core_ext/array/deprecated_conversions.rb +0 -25
- data/lib/active_support/core_ext/date/deprecated_conversions.rb +0 -26
- data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +0 -22
- data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +0 -60
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +0 -26
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +0 -7
- data/lib/active_support/core_ext/range/overlaps.rb +0 -10
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +0 -22
- data/lib/active_support/core_ext/uri.rb +0 -5
- data/lib/active_support/deprecation/instance_delegator.rb +0 -38
- data/lib/active_support/per_thread_registry.rb +0 -65
- data/lib/active_support/ruby_features.rb +0 -7
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module ActiveSupport
|
|
4
|
+
# = \String Inquirer
|
|
5
|
+
#
|
|
4
6
|
# Wrapping a string in this class gives you a prettier way to test
|
|
5
7
|
# for equality. The value returned by <tt>Rails.env</tt> is wrapped
|
|
6
8
|
# in a StringInquirer object, so instead of calling this:
|
|
@@ -11,7 +13,7 @@ module ActiveSupport
|
|
|
11
13
|
#
|
|
12
14
|
# Rails.env.production?
|
|
13
15
|
#
|
|
14
|
-
# == Instantiating a new StringInquirer
|
|
16
|
+
# == Instantiating a new \StringInquirer
|
|
15
17
|
#
|
|
16
18
|
# vehicle = ActiveSupport::StringInquirer.new('car')
|
|
17
19
|
# vehicle.car? # => true
|
|
@@ -22,7 +24,7 @@ module ActiveSupport
|
|
|
22
24
|
method_name.end_with?("?") || super
|
|
23
25
|
end
|
|
24
26
|
|
|
25
|
-
def method_missing(method_name,
|
|
27
|
+
def method_missing(method_name, ...)
|
|
26
28
|
if method_name.end_with?("?")
|
|
27
29
|
self == method_name[0..-2]
|
|
28
30
|
else
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
require "active_support/notifications"
|
|
4
4
|
|
|
5
5
|
module ActiveSupport
|
|
6
|
-
#
|
|
6
|
+
# = Active Support \Subscriber
|
|
7
|
+
#
|
|
8
|
+
# +ActiveSupport::Subscriber+ is an object set to consume
|
|
7
9
|
# ActiveSupport::Notifications. The subscriber dispatches notifications to
|
|
8
10
|
# a registered object based on its given namespace.
|
|
9
11
|
#
|
|
@@ -20,9 +22,9 @@ module ActiveSupport
|
|
|
20
22
|
# end
|
|
21
23
|
# end
|
|
22
24
|
#
|
|
23
|
-
# After configured, whenever a "sql.active_record" notification is
|
|
24
|
-
# it will properly dispatch the event
|
|
25
|
-
# the +sql+ method.
|
|
25
|
+
# After configured, whenever a <tt>"sql.active_record"</tt> notification is
|
|
26
|
+
# published, it will properly dispatch the event
|
|
27
|
+
# (ActiveSupport::Notifications::Event) to the +sql+ method.
|
|
26
28
|
#
|
|
27
29
|
# We can detach a subscriber as well:
|
|
28
30
|
#
|
|
@@ -65,6 +67,7 @@ module ActiveSupport
|
|
|
65
67
|
|
|
66
68
|
# Adds event subscribers for all new methods added to the class.
|
|
67
69
|
def method_added(event)
|
|
70
|
+
super
|
|
68
71
|
# Only public methods are added as subscribers, and only if a notifier
|
|
69
72
|
# has been set up. This means that subscribers will only be set up for
|
|
70
73
|
# classes that call #attach_to.
|
|
@@ -126,38 +129,18 @@ module ActiveSupport
|
|
|
126
129
|
attr_reader :patterns # :nodoc:
|
|
127
130
|
|
|
128
131
|
def initialize
|
|
129
|
-
@queue_key = [self.class.name, object_id].join "-"
|
|
130
132
|
@patterns = {}
|
|
131
133
|
super
|
|
132
134
|
end
|
|
133
135
|
|
|
134
|
-
def
|
|
135
|
-
|
|
136
|
-
event.start!
|
|
137
|
-
parent = event_stack.last
|
|
138
|
-
parent << event if parent
|
|
139
|
-
|
|
140
|
-
event_stack.push event
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
def finish(name, id, payload)
|
|
144
|
-
event = event_stack.pop
|
|
145
|
-
event.finish!
|
|
146
|
-
event.payload.merge!(payload)
|
|
147
|
-
|
|
148
|
-
method = name.split(".").first
|
|
136
|
+
def call(event)
|
|
137
|
+
method = event.name[0, event.name.index(".")]
|
|
149
138
|
send(method, event)
|
|
150
139
|
end
|
|
151
140
|
|
|
152
141
|
def publish_event(event) # :nodoc:
|
|
153
|
-
method = event.name.
|
|
142
|
+
method = event.name[0, event.name.index(".")]
|
|
154
143
|
send(method, event)
|
|
155
144
|
end
|
|
156
|
-
|
|
157
|
-
private
|
|
158
|
-
def event_stack
|
|
159
|
-
registry = ActiveSupport::IsolatedExecutionState[:active_support_subscriber_queue_registry] ||= {}
|
|
160
|
-
registry[@queue_key] ||= []
|
|
161
|
-
end
|
|
162
145
|
end
|
|
163
146
|
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "delegate"
|
|
4
|
+
|
|
5
|
+
module ActiveSupport
|
|
6
|
+
# This is a class for wrapping syntax errors. The purpose of this class
|
|
7
|
+
# is to enhance the backtraces on SyntaxError exceptions to include the
|
|
8
|
+
# source location of the syntax error. That way we can display the error
|
|
9
|
+
# source on error pages in development.
|
|
10
|
+
class SyntaxErrorProxy < DelegateClass(SyntaxError) # :nodoc:
|
|
11
|
+
def backtrace
|
|
12
|
+
parse_message_for_trace + super
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class BacktraceLocation < Struct.new(:path, :lineno, :to_s) # :nodoc:
|
|
16
|
+
def spot(_)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def label
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class BacktraceLocationProxy < DelegateClass(Thread::Backtrace::Location) # :nodoc:
|
|
24
|
+
def initialize(loc, ex)
|
|
25
|
+
super(loc)
|
|
26
|
+
@ex = ex
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def spot(_)
|
|
30
|
+
super(@ex.__getobj__)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def backtrace_locations
|
|
35
|
+
return nil if super.nil?
|
|
36
|
+
|
|
37
|
+
parse_message_for_trace.map { |trace|
|
|
38
|
+
file, line = trace.match(/^(.+?):(\d+).*$/, &:captures) || trace
|
|
39
|
+
BacktraceLocation.new(file, line.to_i, trace)
|
|
40
|
+
# We have to wrap these backtrace locations because we need the
|
|
41
|
+
# spot information to come from the originating exception, not the
|
|
42
|
+
# proxy object that's generating these
|
|
43
|
+
} + super.map { |loc| BacktraceLocationProxy.new(loc, self) }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
def parse_message_for_trace
|
|
48
|
+
if __getobj__.to_s.start_with?("(eval")
|
|
49
|
+
# If the exception is coming from a call to eval, we need to keep
|
|
50
|
+
# the path of the file in which eval was called to ensure we can
|
|
51
|
+
# return the right source fragment to show the location of the
|
|
52
|
+
# error
|
|
53
|
+
location = __getobj__.backtrace_locations[0]
|
|
54
|
+
["#{location.path}:#{location.lineno}: #{__getobj__}"]
|
|
55
|
+
else
|
|
56
|
+
__getobj__.to_s.split("\n")
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "active_support/core_ext/module/delegation"
|
|
4
|
-
require "active_support/core_ext/module/redefine_method"
|
|
5
4
|
require "active_support/core_ext/object/blank"
|
|
6
|
-
require "logger"
|
|
7
5
|
require "active_support/logger"
|
|
8
6
|
|
|
9
7
|
module ActiveSupport
|
|
8
|
+
# = Active Support Tagged Logging
|
|
9
|
+
#
|
|
10
10
|
# Wraps any standard Logger object to provide tagging capabilities.
|
|
11
11
|
#
|
|
12
12
|
# May be called with a block:
|
|
13
13
|
#
|
|
14
14
|
# logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
|
|
15
|
-
# logger.tagged('BCX') { logger.info 'Stuff' }
|
|
16
|
-
# logger.tagged('BCX', "Jason") {
|
|
17
|
-
# logger.tagged('BCX') { logger.tagged('Jason') { logger.info 'Stuff' } }
|
|
15
|
+
# logger.tagged('BCX') { logger.info 'Stuff' } # Logs "[BCX] Stuff"
|
|
16
|
+
# logger.tagged('BCX', "Jason") { |tagged_logger| tagged_logger.info 'Stuff' } # Logs "[BCX] [Jason] Stuff"
|
|
17
|
+
# logger.tagged('BCX') { logger.tagged('Jason') { logger.info 'Stuff' } } # Logs "[BCX] [Jason] Stuff"
|
|
18
18
|
#
|
|
19
19
|
# If called without a block, a new logger will be returned with applied tags:
|
|
20
20
|
#
|
|
@@ -30,52 +30,86 @@ module ActiveSupport
|
|
|
30
30
|
module Formatter # :nodoc:
|
|
31
31
|
# This method is invoked when a log event occurs.
|
|
32
32
|
def call(severity, timestamp, progname, msg)
|
|
33
|
-
super(severity, timestamp, progname,
|
|
33
|
+
super(severity, timestamp, progname, tag_stack.format_message(msg))
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def tagged(*tags)
|
|
37
|
-
|
|
37
|
+
pushed_count = tag_stack.push_tags(tags).size
|
|
38
38
|
yield self
|
|
39
39
|
ensure
|
|
40
|
-
pop_tags(
|
|
40
|
+
pop_tags(pushed_count)
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
def push_tags(*tags)
|
|
44
|
-
tags
|
|
45
|
-
tags.reject!(&:blank?)
|
|
46
|
-
current_tags.concat tags
|
|
47
|
-
tags
|
|
44
|
+
tag_stack.push_tags(tags)
|
|
48
45
|
end
|
|
49
46
|
|
|
50
|
-
def pop_tags(
|
|
51
|
-
|
|
47
|
+
def pop_tags(count = 1)
|
|
48
|
+
tag_stack.pop_tags(count)
|
|
52
49
|
end
|
|
53
50
|
|
|
54
51
|
def clear_tags!
|
|
55
|
-
|
|
52
|
+
tag_stack.clear
|
|
56
53
|
end
|
|
57
54
|
|
|
58
|
-
def
|
|
55
|
+
def tag_stack
|
|
59
56
|
# We use our object ID here to avoid conflicting with other instances
|
|
60
|
-
|
|
61
|
-
IsolatedExecutionState[thread_key] ||=
|
|
57
|
+
@thread_key ||= "activesupport_tagged_logging_tags:#{object_id}"
|
|
58
|
+
IsolatedExecutionState[@thread_key] ||= TagStack.new
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def current_tags
|
|
62
|
+
tag_stack.tags
|
|
62
63
|
end
|
|
63
64
|
|
|
64
65
|
def tags_text
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
tag_stack.format_message("")
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
class TagStack # :nodoc:
|
|
71
|
+
attr_reader :tags
|
|
72
|
+
|
|
73
|
+
def initialize
|
|
74
|
+
@tags = []
|
|
75
|
+
@tags_string = nil
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def push_tags(tags)
|
|
79
|
+
@tags_string = nil
|
|
80
|
+
tags.flatten!
|
|
81
|
+
tags.reject!(&:blank?)
|
|
82
|
+
@tags.concat(tags)
|
|
83
|
+
tags
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def pop_tags(count)
|
|
87
|
+
@tags_string = nil
|
|
88
|
+
@tags.pop(count)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def clear
|
|
92
|
+
@tags_string = nil
|
|
93
|
+
@tags.clear
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def format_message(message)
|
|
97
|
+
if @tags.empty?
|
|
98
|
+
message
|
|
99
|
+
elsif @tags.size == 1
|
|
100
|
+
"[#{@tags[0]}] #{message}"
|
|
101
|
+
else
|
|
102
|
+
@tags_string ||= "[#{@tags.join("] [")}] "
|
|
103
|
+
"#{@tags_string}#{message}"
|
|
70
104
|
end
|
|
71
105
|
end
|
|
72
106
|
end
|
|
73
107
|
|
|
74
108
|
module LocalTagStorage # :nodoc:
|
|
75
|
-
attr_accessor :
|
|
109
|
+
attr_accessor :tag_stack
|
|
76
110
|
|
|
77
111
|
def self.extended(base)
|
|
78
|
-
base.
|
|
112
|
+
base.tag_stack = TagStack.new
|
|
79
113
|
end
|
|
80
114
|
end
|
|
81
115
|
|
|
@@ -83,7 +117,11 @@ module ActiveSupport
|
|
|
83
117
|
logger = logger.clone
|
|
84
118
|
|
|
85
119
|
if logger.formatter
|
|
86
|
-
logger.formatter = logger.formatter.
|
|
120
|
+
logger.formatter = logger.formatter.clone
|
|
121
|
+
|
|
122
|
+
# Workaround for https://bugs.ruby-lang.org/issues/20250
|
|
123
|
+
# Can be removed when Ruby 3.4 is the least supported version.
|
|
124
|
+
logger.formatter.object_id if logger.formatter.is_a?(Proc)
|
|
87
125
|
else
|
|
88
126
|
# Ensure we set a default formatter so we aren't extending nil!
|
|
89
127
|
logger.formatter = ActiveSupport::Logger::SimpleFormatter.new
|
|
@@ -95,20 +133,6 @@ module ActiveSupport
|
|
|
95
133
|
|
|
96
134
|
delegate :push_tags, :pop_tags, :clear_tags!, to: :formatter
|
|
97
135
|
|
|
98
|
-
def broadcast_to(other_logger) # :nodoc:
|
|
99
|
-
define_singleton_method(:formatter=) do |formatter|
|
|
100
|
-
other_logger.formatter ||= formatter
|
|
101
|
-
|
|
102
|
-
other_logger.formatter.singleton_class.redefine_method(:current_tags) do
|
|
103
|
-
formatter.current_tags
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
super(formatter)
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
self.formatter = self.formatter.clone
|
|
110
|
-
end
|
|
111
|
-
|
|
112
136
|
def tagged(*tags)
|
|
113
137
|
if block_given?
|
|
114
138
|
formatter.tagged(*tags) { yield self }
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
gem "minitest" # make sure we get the gem, not stdlib
|
|
4
3
|
require "minitest"
|
|
5
4
|
require "active_support/testing/tagged_logging"
|
|
6
5
|
require "active_support/testing/setup_and_teardown"
|
|
6
|
+
require "active_support/testing/tests_without_assertions"
|
|
7
7
|
require "active_support/testing/assertions"
|
|
8
|
+
require "active_support/testing/error_reporter_assertions"
|
|
8
9
|
require "active_support/testing/deprecation"
|
|
9
10
|
require "active_support/testing/declarative"
|
|
10
11
|
require "active_support/testing/isolation"
|
|
11
12
|
require "active_support/testing/constant_lookup"
|
|
12
13
|
require "active_support/testing/time_helpers"
|
|
14
|
+
require "active_support/testing/constant_stubbing"
|
|
13
15
|
require "active_support/testing/file_fixtures"
|
|
14
16
|
require "active_support/testing/parallelization"
|
|
15
17
|
require "active_support/testing/parallelize_executor"
|
|
@@ -66,7 +68,7 @@ module ActiveSupport
|
|
|
66
68
|
# The default parallelization method is to fork processes. If you'd like to
|
|
67
69
|
# use threads instead you can pass <tt>with: :threads</tt> to the +parallelize+
|
|
68
70
|
# method. Note the threaded parallelization does not create multiple
|
|
69
|
-
#
|
|
71
|
+
# databases and will not work with system tests.
|
|
70
72
|
#
|
|
71
73
|
# parallelize(workers: :number_of_processors, with: :threads)
|
|
72
74
|
#
|
|
@@ -77,11 +79,9 @@ module ActiveSupport
|
|
|
77
79
|
# number of tests to run is above the +threshold+ param. The default value is
|
|
78
80
|
# 50, and it's configurable via +config.active_support.test_parallelization_threshold+.
|
|
79
81
|
def parallelize(workers: :number_of_processors, with: :processes, threshold: ActiveSupport.test_parallelization_threshold)
|
|
80
|
-
workers = Concurrent.
|
|
82
|
+
workers = Concurrent.processor_count if workers == :number_of_processors
|
|
81
83
|
workers = ENV["PARALLEL_WORKERS"].to_i if ENV["PARALLEL_WORKERS"]
|
|
82
84
|
|
|
83
|
-
return if workers <= 1
|
|
84
|
-
|
|
85
85
|
Minitest.parallel_executor = ActiveSupport::Testing::ParallelizeExecutor.new(size: workers, with: with, threshold: threshold)
|
|
86
86
|
end
|
|
87
87
|
|
|
@@ -118,34 +118,187 @@ module ActiveSupport
|
|
|
118
118
|
def parallelize_teardown(&block)
|
|
119
119
|
ActiveSupport::Testing::Parallelization.run_cleanup_hook(&block)
|
|
120
120
|
end
|
|
121
|
+
|
|
122
|
+
# :singleton-method: fixture_paths
|
|
123
|
+
#
|
|
124
|
+
# Returns the ActiveRecord::FixtureSet collection.
|
|
125
|
+
#
|
|
126
|
+
# In your +test_helper.rb+ you must have <tt>require "rails/test_help"</tt>.
|
|
127
|
+
|
|
128
|
+
# :singleton-method: fixture_paths=
|
|
129
|
+
#
|
|
130
|
+
# :call-seq:
|
|
131
|
+
# fixture_paths=(fixture_paths)
|
|
132
|
+
#
|
|
133
|
+
# Sets the given path to the fixture set.
|
|
134
|
+
#
|
|
135
|
+
# Can also append multiple paths.
|
|
136
|
+
#
|
|
137
|
+
# ActiveSupport::TestCase.fixture_paths << "component1/test/fixtures"
|
|
138
|
+
#
|
|
139
|
+
# In your +test_helper.rb+ you must have <tt>require "rails/test_help"</tt>.
|
|
121
140
|
end
|
|
122
141
|
|
|
123
142
|
alias_method :method_name, :name
|
|
124
143
|
|
|
125
144
|
include ActiveSupport::Testing::TaggedLogging
|
|
126
145
|
prepend ActiveSupport::Testing::SetupAndTeardown
|
|
146
|
+
prepend ActiveSupport::Testing::TestsWithoutAssertions
|
|
127
147
|
include ActiveSupport::Testing::Assertions
|
|
148
|
+
include ActiveSupport::Testing::ErrorReporterAssertions
|
|
128
149
|
include ActiveSupport::Testing::Deprecation
|
|
150
|
+
include ActiveSupport::Testing::ConstantStubbing
|
|
129
151
|
include ActiveSupport::Testing::TimeHelpers
|
|
130
152
|
include ActiveSupport::Testing::FileFixtures
|
|
131
153
|
extend ActiveSupport::Testing::Declarative
|
|
132
154
|
|
|
133
|
-
|
|
134
|
-
|
|
155
|
+
##
|
|
156
|
+
# :method: assert_not_empty
|
|
157
|
+
#
|
|
158
|
+
# :call-seq:
|
|
159
|
+
# assert_not_empty(obj, msg = nil)
|
|
160
|
+
#
|
|
161
|
+
# Alias for: refute_empty[https://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-refute_empty]
|
|
162
|
+
|
|
163
|
+
#
|
|
135
164
|
alias :assert_not_empty :refute_empty
|
|
165
|
+
|
|
166
|
+
##
|
|
167
|
+
# :method: assert_not_equal
|
|
168
|
+
#
|
|
169
|
+
# :call-seq:
|
|
170
|
+
# assert_not_equal(exp, act, msg = nil)
|
|
171
|
+
#
|
|
172
|
+
# Alias for: refute_equal[https://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-refute_equal]
|
|
173
|
+
|
|
174
|
+
#
|
|
136
175
|
alias :assert_not_equal :refute_equal
|
|
176
|
+
|
|
177
|
+
##
|
|
178
|
+
# :method: assert_not_in_delta
|
|
179
|
+
#
|
|
180
|
+
# :call-seq:
|
|
181
|
+
# assert_not_in_delta(exp, act, delta = 0.001, msg = nil)
|
|
182
|
+
#
|
|
183
|
+
# Alias for: refute_in_delta[https://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-refute_in_delta]
|
|
184
|
+
|
|
185
|
+
#
|
|
137
186
|
alias :assert_not_in_delta :refute_in_delta
|
|
187
|
+
|
|
188
|
+
##
|
|
189
|
+
# :method: assert_not_in_epsilon
|
|
190
|
+
#
|
|
191
|
+
# :call-seq:
|
|
192
|
+
# assert_not_in_epsilon(a, b, epsilon = 0.001, msg = nil)
|
|
193
|
+
#
|
|
194
|
+
# Alias for: refute_in_epsilon[https://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-refute_in_epsilon]
|
|
195
|
+
|
|
196
|
+
#
|
|
138
197
|
alias :assert_not_in_epsilon :refute_in_epsilon
|
|
198
|
+
|
|
199
|
+
##
|
|
200
|
+
# :method: assert_not_includes
|
|
201
|
+
#
|
|
202
|
+
# :call-seq:
|
|
203
|
+
# assert_not_includes(collection, obj, msg = nil)
|
|
204
|
+
#
|
|
205
|
+
# Alias for: refute_includes[https://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-refute_includes]
|
|
206
|
+
|
|
207
|
+
#
|
|
139
208
|
alias :assert_not_includes :refute_includes
|
|
209
|
+
|
|
210
|
+
##
|
|
211
|
+
# :method: assert_not_instance_of
|
|
212
|
+
#
|
|
213
|
+
# :call-seq:
|
|
214
|
+
# assert_not_instance_of(cls, obj, msg = nil)
|
|
215
|
+
#
|
|
216
|
+
# Alias for: refute_instance_of[https://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-refute_instance_of]
|
|
217
|
+
|
|
218
|
+
#
|
|
140
219
|
alias :assert_not_instance_of :refute_instance_of
|
|
220
|
+
|
|
221
|
+
##
|
|
222
|
+
# :method: assert_not_kind_of
|
|
223
|
+
#
|
|
224
|
+
# :call-seq:
|
|
225
|
+
# assert_not_kind_of(cls, obj, msg = nil)
|
|
226
|
+
#
|
|
227
|
+
# Alias for: refute_kind_of[https://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-refute_kind_of]
|
|
228
|
+
|
|
229
|
+
#
|
|
141
230
|
alias :assert_not_kind_of :refute_kind_of
|
|
231
|
+
|
|
232
|
+
##
|
|
233
|
+
# :method: assert_no_match
|
|
234
|
+
#
|
|
235
|
+
# :call-seq:
|
|
236
|
+
# assert_no_match(matcher, obj, msg = nil)
|
|
237
|
+
#
|
|
238
|
+
# Alias for: refute_match[https://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-refute_match]
|
|
239
|
+
|
|
240
|
+
#
|
|
142
241
|
alias :assert_no_match :refute_match
|
|
242
|
+
|
|
243
|
+
##
|
|
244
|
+
# :method: assert_not_nil
|
|
245
|
+
#
|
|
246
|
+
# :call-seq:
|
|
247
|
+
# assert_not_nil(obj, msg = nil)
|
|
248
|
+
#
|
|
249
|
+
# Alias for: refute_nil[https://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-refute_nil]
|
|
250
|
+
|
|
251
|
+
#
|
|
143
252
|
alias :assert_not_nil :refute_nil
|
|
253
|
+
|
|
254
|
+
##
|
|
255
|
+
# :method: assert_not_operator
|
|
256
|
+
#
|
|
257
|
+
# :call-seq:
|
|
258
|
+
# assert_not_operator(o1, op, o2 = UNDEFINED, msg = nil)
|
|
259
|
+
#
|
|
260
|
+
# Alias for: refute_operator[https://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-refute_operator]
|
|
261
|
+
|
|
262
|
+
#
|
|
144
263
|
alias :assert_not_operator :refute_operator
|
|
264
|
+
|
|
265
|
+
##
|
|
266
|
+
# :method: assert_not_predicate
|
|
267
|
+
#
|
|
268
|
+
# :call-seq:
|
|
269
|
+
# assert_not_predicate(o1, op, msg = nil)
|
|
270
|
+
#
|
|
271
|
+
# Alias for: refute_predicate[https://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-refute_predicate]
|
|
272
|
+
|
|
273
|
+
#
|
|
145
274
|
alias :assert_not_predicate :refute_predicate
|
|
275
|
+
|
|
276
|
+
##
|
|
277
|
+
# :method: assert_not_respond_to
|
|
278
|
+
#
|
|
279
|
+
# :call-seq:
|
|
280
|
+
# assert_not_respond_to(obj, meth, msg = nil)
|
|
281
|
+
#
|
|
282
|
+
# Alias for: refute_respond_to[https://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-refute_respond_to]
|
|
283
|
+
|
|
284
|
+
#
|
|
146
285
|
alias :assert_not_respond_to :refute_respond_to
|
|
286
|
+
|
|
287
|
+
##
|
|
288
|
+
# :method: assert_not_same
|
|
289
|
+
#
|
|
290
|
+
# :call-seq:
|
|
291
|
+
# assert_not_same(exp, act, msg = nil)
|
|
292
|
+
#
|
|
293
|
+
# Alias for: refute_same[https://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-refute_same]
|
|
294
|
+
|
|
295
|
+
#
|
|
147
296
|
alias :assert_not_same :refute_same
|
|
148
297
|
|
|
149
298
|
ActiveSupport.run_load_hooks(:active_support_test_case, self)
|
|
299
|
+
|
|
300
|
+
def inspect # :nodoc:
|
|
301
|
+
Object.instance_method(:to_s).bind_call(self)
|
|
302
|
+
end
|
|
150
303
|
end
|
|
151
304
|
end
|
|
@@ -7,9 +7,9 @@ module ActiveSupport
|
|
|
7
7
|
module Assertions
|
|
8
8
|
UNTRACKED = Object.new # :nodoc:
|
|
9
9
|
|
|
10
|
-
# Asserts that an expression is not truthy. Passes if
|
|
11
|
-
# +
|
|
12
|
-
#
|
|
10
|
+
# Asserts that an expression is not truthy. Passes if +object+ is +nil+ or
|
|
11
|
+
# +false+. "Truthy" means "considered true in a conditional" like <tt>if
|
|
12
|
+
# foo</tt>.
|
|
13
13
|
#
|
|
14
14
|
# assert_not nil # => true
|
|
15
15
|
# assert_not false # => true
|
|
@@ -23,6 +23,21 @@ module ActiveSupport
|
|
|
23
23
|
assert !object, message
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
# Asserts that a block raises one of +exp+. This is an enhancement of the
|
|
27
|
+
# standard Minitest assertion method with the ability to test error
|
|
28
|
+
# messages.
|
|
29
|
+
#
|
|
30
|
+
# assert_raises(ArgumentError, match: /incorrect param/i) do
|
|
31
|
+
# perform_service(param: 'exception')
|
|
32
|
+
# end
|
|
33
|
+
#
|
|
34
|
+
def assert_raises(*exp, match: nil, &block)
|
|
35
|
+
error = super(*exp, &block)
|
|
36
|
+
assert_match(match, error.message) if match
|
|
37
|
+
error
|
|
38
|
+
end
|
|
39
|
+
alias :assert_raise :assert_raises
|
|
40
|
+
|
|
26
41
|
# Assertion that the block should not raise an exception.
|
|
27
42
|
#
|
|
28
43
|
# Passes if evaluated code in the yielded block raises no exception.
|
|
@@ -31,7 +46,7 @@ module ActiveSupport
|
|
|
31
46
|
# perform_service(param: 'no_exception')
|
|
32
47
|
# end
|
|
33
48
|
def assert_nothing_raised
|
|
34
|
-
yield
|
|
49
|
+
yield.tap { assert(true) }
|
|
35
50
|
rescue => error
|
|
36
51
|
raise Minitest::UnexpectedError.new(error)
|
|
37
52
|
end
|
|
@@ -50,7 +65,7 @@ module ActiveSupport
|
|
|
50
65
|
# end
|
|
51
66
|
#
|
|
52
67
|
# An arbitrary positive or negative difference can be specified.
|
|
53
|
-
# The default is
|
|
68
|
+
# The default is +1+.
|
|
54
69
|
#
|
|
55
70
|
# assert_difference 'Article.count', -1 do
|
|
56
71
|
# post :delete, params: { id: ... }
|
|
@@ -102,9 +117,10 @@ module ActiveSupport
|
|
|
102
117
|
retval = _assert_nothing_raised_or_warn("assert_difference", &block)
|
|
103
118
|
|
|
104
119
|
expressions.zip(exps, before) do |(code, diff), exp, before_value|
|
|
105
|
-
|
|
120
|
+
actual = exp.call
|
|
121
|
+
error = "#{code.inspect} didn't change by #{diff}, but by #{actual - before_value}"
|
|
106
122
|
error = "#{message}.\n#{error}" if message
|
|
107
|
-
assert_equal(before_value + diff,
|
|
123
|
+
assert_equal(before_value + diff, actual, error)
|
|
108
124
|
end
|
|
109
125
|
|
|
110
126
|
retval
|
|
@@ -179,7 +195,7 @@ module ActiveSupport
|
|
|
179
195
|
retval = _assert_nothing_raised_or_warn("assert_changes", &block)
|
|
180
196
|
|
|
181
197
|
unless from == UNTRACKED
|
|
182
|
-
error = "Expected change from #{from.inspect}"
|
|
198
|
+
error = "Expected change from #{from.inspect}, got #{before.inspect}"
|
|
183
199
|
error = "#{message}.\n#{error}" if message
|
|
184
200
|
assert from === before, error
|
|
185
201
|
end
|
|
@@ -187,12 +203,12 @@ module ActiveSupport
|
|
|
187
203
|
after = exp.call
|
|
188
204
|
|
|
189
205
|
error = "#{expression.inspect} didn't change"
|
|
190
|
-
error = "#{error}. It was already #{to}" if before == to
|
|
206
|
+
error = "#{error}. It was already #{to.inspect}" if before == to
|
|
191
207
|
error = "#{message}.\n#{error}" if message
|
|
192
208
|
refute_equal before, after, error
|
|
193
209
|
|
|
194
210
|
unless to == UNTRACKED
|
|
195
|
-
error = "Expected change to #{to}\n"
|
|
211
|
+
error = "Expected change to #{to.inspect}, got #{after.inspect}\n"
|
|
196
212
|
error = "#{message}.\n#{error}" if message
|
|
197
213
|
assert to === after, error
|
|
198
214
|
end
|
|
@@ -207,7 +223,7 @@ module ActiveSupport
|
|
|
207
223
|
# post :create, params: { status: { ok: true } }
|
|
208
224
|
# end
|
|
209
225
|
#
|
|
210
|
-
# Provide the optional keyword argument
|
|
226
|
+
# Provide the optional keyword argument +:from+ to specify the expected
|
|
211
227
|
# initial value.
|
|
212
228
|
#
|
|
213
229
|
# assert_no_changes -> { Status.all_good? }, from: true do
|
|
@@ -226,7 +242,7 @@ module ActiveSupport
|
|
|
226
242
|
retval = _assert_nothing_raised_or_warn("assert_no_changes", &block)
|
|
227
243
|
|
|
228
244
|
unless from == UNTRACKED
|
|
229
|
-
error = "Expected initial value of #{from.inspect}"
|
|
245
|
+
error = "Expected initial value of #{from.inspect}, got #{before.inspect}"
|
|
230
246
|
error = "#{message}.\n#{error}" if message
|
|
231
247
|
assert from === before, error
|
|
232
248
|
end
|