activesupport 5.1.7 → 7.0.4.1
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 +259 -585
- data/MIT-LICENSE +1 -1
- data/README.rdoc +6 -5
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/all.rb +2 -0
- data/lib/active_support/array_inquirer.rb +4 -2
- data/lib/active_support/backtrace_cleaner.rb +33 -5
- data/lib/active_support/benchmarkable.rb +5 -3
- data/lib/active_support/builder.rb +2 -0
- data/lib/active_support/cache/file_store.rb +50 -43
- data/lib/active_support/cache/mem_cache_store.rb +194 -67
- data/lib/active_support/cache/memory_store.rb +70 -34
- data/lib/active_support/cache/null_store.rb +18 -3
- data/lib/active_support/cache/redis_cache_store.rb +474 -0
- data/lib/active_support/cache/strategy/local_cache.rb +73 -50
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
- data/lib/active_support/cache.rb +556 -220
- data/lib/active_support/callbacks.rb +264 -159
- data/lib/active_support/code_generator.rb +65 -0
- data/lib/active_support/concern.rb +81 -8
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +16 -0
- data/lib/active_support/concurrency/share_lock.rb +4 -3
- data/lib/active_support/configurable.rb +17 -16
- data/lib/active_support/configuration_file.rb +51 -0
- data/lib/active_support/core_ext/array/access.rb +18 -8
- data/lib/active_support/core_ext/array/conversions.rb +20 -17
- data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array/extract_options.rb +2 -0
- data/lib/active_support/core_ext/array/grouping.rb +8 -6
- data/lib/active_support/core_ext/array/inquiry.rb +4 -2
- data/lib/active_support/core_ext/array/wrap.rb +2 -0
- data/lib/active_support/core_ext/array.rb +4 -1
- data/lib/active_support/core_ext/benchmark.rb +4 -2
- data/lib/active_support/core_ext/big_decimal/conversions.rb +3 -1
- data/lib/active_support/core_ext/big_decimal.rb +2 -0
- data/lib/active_support/core_ext/class/attribute.rb +50 -47
- data/lib/active_support/core_ext/class/attribute_accessors.rb +2 -0
- data/lib/active_support/core_ext/class/subclasses.rb +10 -24
- data/lib/active_support/core_ext/class.rb +2 -0
- data/lib/active_support/core_ext/date/acts_like.rb +2 -0
- data/lib/active_support/core_ext/date/blank.rb +3 -1
- data/lib/active_support/core_ext/date/calculations.rb +17 -14
- data/lib/active_support/core_ext/date/conversions.rb +24 -22
- data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/date/zones.rb +2 -0
- data/lib/active_support/core_ext/date.rb +3 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +65 -41
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -1
- data/lib/active_support/core_ext/date_and_time/zones.rb +2 -1
- data/lib/active_support/core_ext/date_time/acts_like.rb +2 -0
- data/lib/active_support/core_ext/date_time/blank.rb +3 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +3 -1
- data/lib/active_support/core_ext/date_time/compatibility.rb +7 -5
- data/lib/active_support/core_ext/date_time/conversions.rb +15 -14
- data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/date_time.rb +3 -0
- data/lib/active_support/core_ext/digest/uuid.rb +42 -14
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +244 -72
- data/lib/active_support/core_ext/file/atomic.rb +6 -2
- data/lib/active_support/core_ext/file.rb +2 -0
- data/lib/active_support/core_ext/hash/conversions.rb +7 -6
- data/lib/active_support/core_ext/hash/deep_merge.rb +8 -12
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +4 -2
- data/lib/active_support/core_ext/hash/indifferent_access.rb +5 -3
- data/lib/active_support/core_ext/hash/keys.rb +4 -31
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +8 -29
- data/lib/active_support/core_ext/hash.rb +3 -2
- data/lib/active_support/core_ext/integer/inflections.rb +2 -0
- data/lib/active_support/core_ext/integer/multiple.rb +3 -1
- data/lib/active_support/core_ext/integer/time.rb +7 -14
- data/lib/active_support/core_ext/integer.rb +2 -0
- data/lib/active_support/core_ext/kernel/concern.rb +2 -0
- data/lib/active_support/core_ext/kernel/reporting.rb +6 -4
- data/lib/active_support/core_ext/kernel/singleton_class.rb +3 -1
- data/lib/active_support/core_ext/kernel.rb +2 -1
- data/lib/active_support/core_ext/load_error.rb +3 -8
- data/lib/active_support/core_ext/module/aliasing.rb +2 -0
- data/lib/active_support/core_ext/module/anonymous.rb +2 -0
- data/lib/active_support/core_ext/module/attr_internal.rb +4 -2
- data/lib/active_support/core_ext/module/attribute_accessors.rb +46 -56
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +36 -27
- data/lib/active_support/core_ext/module/concerning.rb +15 -10
- data/lib/active_support/core_ext/module/delegation.rb +97 -58
- data/lib/active_support/core_ext/module/deprecation.rb +2 -0
- data/lib/active_support/core_ext/module/introspection.rb +18 -15
- data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
- data/lib/active_support/core_ext/module/remove_method.rb +5 -23
- data/lib/active_support/core_ext/module.rb +3 -1
- data/lib/active_support/core_ext/name_error.rb +30 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +134 -129
- data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
- data/lib/active_support/core_ext/numeric/time.rb +7 -15
- data/lib/active_support/core_ext/numeric.rb +3 -1
- data/lib/active_support/core_ext/object/acts_like.rb +41 -6
- data/lib/active_support/core_ext/object/blank.rb +15 -5
- data/lib/active_support/core_ext/object/conversions.rb +2 -0
- data/lib/active_support/core_ext/object/deep_dup.rb +3 -1
- data/lib/active_support/core_ext/object/duplicable.rb +16 -110
- data/lib/active_support/core_ext/object/inclusion.rb +2 -0
- data/lib/active_support/core_ext/object/instance_variables.rb +2 -0
- data/lib/active_support/core_ext/object/json.rb +51 -26
- data/lib/active_support/core_ext/object/to_param.rb +2 -0
- data/lib/active_support/core_ext/object/to_query.rb +4 -2
- data/lib/active_support/core_ext/object/try.rb +26 -14
- data/lib/active_support/core_ext/object/with_options.rb +24 -3
- data/lib/active_support/core_ext/object.rb +2 -0
- 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 +57 -0
- data/lib/active_support/core_ext/range/conversions.rb +35 -25
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/range/each.rb +6 -3
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +7 -0
- data/lib/active_support/core_ext/range/overlaps.rb +3 -1
- data/lib/active_support/core_ext/range.rb +4 -1
- data/lib/active_support/core_ext/regexp.rb +10 -5
- data/lib/active_support/core_ext/securerandom.rb +25 -3
- data/lib/active_support/core_ext/string/access.rb +7 -16
- data/lib/active_support/core_ext/string/behavior.rb +2 -0
- data/lib/active_support/core_ext/string/conversions.rb +5 -2
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +44 -1
- data/lib/active_support/core_ext/string/indent.rb +2 -0
- data/lib/active_support/core_ext/string/inflections.rb +69 -16
- data/lib/active_support/core_ext/string/inquiry.rb +4 -1
- data/lib/active_support/core_ext/string/multibyte.rb +9 -4
- data/lib/active_support/core_ext/string/output_safety.rb +135 -27
- data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
- data/lib/active_support/core_ext/string/strip.rb +5 -1
- data/lib/active_support/core_ext/string/zones.rb +2 -0
- data/lib/active_support/core_ext/string.rb +2 -0
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
- data/lib/active_support/core_ext/symbol.rb +3 -0
- data/lib/active_support/core_ext/time/acts_like.rb +2 -0
- data/lib/active_support/core_ext/time/calculations.rb +81 -24
- data/lib/active_support/core_ext/time/compatibility.rb +4 -2
- data/lib/active_support/core_ext/time/conversions.rb +17 -12
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/time/zones.rb +12 -25
- data/lib/active_support/core_ext/time.rb +3 -0
- data/lib/active_support/core_ext/uri.rb +4 -23
- data/lib/active_support/core_ext.rb +4 -1
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +226 -0
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +12 -18
- data/lib/active_support/dependencies/require_dependency.rb +28 -0
- data/lib/active_support/dependencies.rb +59 -715
- data/lib/active_support/deprecation/behaviors.rb +48 -13
- data/lib/active_support/deprecation/constant_accessor.rb +4 -2
- data/lib/active_support/deprecation/disallowed.rb +56 -0
- data/lib/active_support/deprecation/instance_delegator.rb +2 -1
- data/lib/active_support/deprecation/method_wrappers.rb +29 -21
- data/lib/active_support/deprecation/proxy_wrappers.rb +34 -8
- data/lib/active_support/deprecation/reporting.rb +54 -9
- data/lib/active_support/deprecation.rb +10 -3
- data/lib/active_support/descendants_tracker.rb +192 -34
- data/lib/active_support/digest.rb +22 -0
- data/lib/active_support/duration/iso8601_parser.rb +9 -9
- data/lib/active_support/duration/iso8601_serializer.rb +29 -15
- data/lib/active_support/duration.rb +158 -72
- data/lib/active_support/encrypted_configuration.rb +56 -0
- data/lib/active_support/encrypted_file.rb +129 -0
- data/lib/active_support/environment_inquirer.rb +20 -0
- data/lib/active_support/error_reporter.rb +117 -0
- data/lib/active_support/evented_file_update_checker.rb +87 -122
- 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 +46 -21
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/executor.rb +2 -0
- data/lib/active_support/file_update_checker.rb +2 -1
- data/lib/active_support/fork_tracker.rb +71 -0
- data/lib/active_support/gem_version.rb +7 -5
- data/lib/active_support/gzip.rb +2 -0
- data/lib/active_support/hash_with_indifferent_access.rb +126 -42
- data/lib/active_support/html_safe_translation.rb +43 -0
- data/lib/active_support/i18n.rb +5 -1
- data/lib/active_support/i18n_railtie.rb +19 -14
- data/lib/active_support/inflections.rb +2 -0
- data/lib/active_support/inflector/inflections.rb +41 -14
- data/lib/active_support/inflector/methods.rb +73 -87
- data/lib/active_support/inflector/transliterate.rb +56 -18
- data/lib/active_support/inflector.rb +2 -0
- data/lib/active_support/isolated_execution_state.rb +72 -0
- data/lib/active_support/json/decoding.rb +27 -26
- data/lib/active_support/json/encoding.rb +16 -6
- data/lib/active_support/json.rb +2 -0
- data/lib/active_support/key_generator.rb +25 -38
- data/lib/active_support/lazy_load_hooks.rb +35 -6
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +8 -4
- data/lib/active_support/log_subscriber/test_helper.rb +4 -2
- data/lib/active_support/log_subscriber.rb +54 -13
- data/lib/active_support/logger.rb +4 -17
- data/lib/active_support/logger_silence.rb +13 -20
- data/lib/active_support/logger_thread_safe_level.rb +48 -10
- data/lib/active_support/message_encryptor.rb +111 -37
- data/lib/active_support/message_verifier.rb +124 -21
- data/lib/active_support/messages/metadata.rb +80 -0
- data/lib/active_support/messages/rotation_configuration.rb +23 -0
- data/lib/active_support/messages/rotator.rb +57 -0
- data/lib/active_support/multibyte/chars.rb +19 -76
- data/lib/active_support/multibyte/unicode.rb +9 -331
- data/lib/active_support/multibyte.rb +3 -1
- data/lib/active_support/notifications/fanout.rb +165 -37
- data/lib/active_support/notifications/instrumenter.rb +92 -11
- data/lib/active_support/notifications.rb +96 -30
- data/lib/active_support/number_helper/number_converter.rb +8 -9
- data/lib/active_support/number_helper/number_to_currency_converter.rb +14 -12
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +6 -3
- data/lib/active_support/number_helper/number_to_human_converter.rb +6 -3
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +7 -4
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +6 -3
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +14 -27
- data/lib/active_support/number_helper/rounding_helper.rb +16 -34
- data/lib/active_support/number_helper.rb +38 -12
- data/lib/active_support/option_merger.rb +19 -6
- data/lib/active_support/ordered_hash.rb +4 -2
- data/lib/active_support/ordered_options.rb +18 -6
- data/lib/active_support/parameter_filter.rb +138 -0
- data/lib/active_support/per_thread_registry.rb +8 -1
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +3 -10
- data/lib/active_support/railtie.rb +112 -11
- data/lib/active_support/reloader.rb +12 -11
- data/lib/active_support/rescuable.rb +19 -18
- data/lib/active_support/ruby_features.rb +7 -0
- data/lib/active_support/secure_compare_rotator.rb +51 -0
- data/lib/active_support/security_utils.rb +26 -15
- data/lib/active_support/string_inquirer.rb +4 -3
- data/lib/active_support/subscriber.rb +81 -42
- data/lib/active_support/tagged_logging.rb +45 -9
- data/lib/active_support/test_case.rb +86 -2
- data/lib/active_support/testing/assertions.rb +89 -21
- data/lib/active_support/testing/autorun.rb +2 -0
- data/lib/active_support/testing/constant_lookup.rb +2 -0
- data/lib/active_support/testing/declarative.rb +2 -0
- data/lib/active_support/testing/deprecation.rb +54 -2
- data/lib/active_support/testing/file_fixtures.rb +4 -0
- data/lib/active_support/testing/isolation.rb +6 -4
- data/lib/active_support/testing/method_call_assertions.rb +34 -5
- data/lib/active_support/testing/parallelization/server.rb +82 -0
- data/lib/active_support/testing/parallelization/worker.rb +103 -0
- data/lib/active_support/testing/parallelization.rb +55 -0
- data/lib/active_support/testing/parallelize_executor.rb +76 -0
- data/lib/active_support/testing/setup_and_teardown.rb +12 -7
- data/lib/active_support/testing/stream.rb +6 -7
- data/lib/active_support/testing/tagged_logging.rb +3 -1
- data/lib/active_support/testing/time_helpers.rb +91 -15
- data/lib/active_support/time.rb +2 -0
- data/lib/active_support/time_with_zone.rb +168 -56
- data/lib/active_support/values/time_zone.rb +85 -37
- data/lib/active_support/version.rb +3 -1
- data/lib/active_support/xml_mini/jdom.rb +6 -5
- data/lib/active_support/xml_mini/libxml.rb +9 -7
- data/lib/active_support/xml_mini/libxmlsax.rb +7 -5
- data/lib/active_support/xml_mini/nokogiri.rb +8 -6
- data/lib/active_support/xml_mini/nokogirisax.rb +6 -4
- data/lib/active_support/xml_mini/rexml.rb +13 -4
- data/lib/active_support/xml_mini.rb +10 -15
- data/lib/active_support.rb +30 -9
- metadata +76 -35
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
- data/lib/active_support/core_ext/hash/compact.rb +0 -27
- data/lib/active_support/core_ext/hash/transform_values.rb +0 -30
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
- data/lib/active_support/core_ext/marshal.rb +0 -22
- data/lib/active_support/core_ext/module/reachable.rb +0 -8
- data/lib/active_support/core_ext/numeric/inquiry.rb +0 -26
- data/lib/active_support/core_ext/range/include_range.rb +0 -23
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,9 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/deprecation"
|
2
|
-
require "active_support/core_ext/regexp"
|
3
4
|
|
4
5
|
module ActiveSupport
|
5
6
|
module Testing
|
6
|
-
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
|
7
31
|
def assert_deprecated(match = nil, deprecator = nil, &block)
|
8
32
|
result, warnings = collect_deprecations(deprecator, &block)
|
9
33
|
assert !warnings.empty?, "Expected a deprecation warning within the block but received none"
|
@@ -14,12 +38,40 @@ module ActiveSupport
|
|
14
38
|
result
|
15
39
|
end
|
16
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
|
17
56
|
def assert_not_deprecated(deprecator = nil, &block)
|
18
57
|
result, deprecations = collect_deprecations(deprecator, &block)
|
19
58
|
assert deprecations.empty?, "Expected no deprecation warning within the block but received #{deprecations.size}: \n #{deprecations * "\n "}"
|
20
59
|
result
|
21
60
|
end
|
22
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"]
|
23
75
|
def collect_deprecations(deprecator = nil)
|
24
76
|
deprecator ||= ActiveSupport::Deprecation
|
25
77
|
old_behavior = deprecator.behavior
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveSupport
|
2
4
|
module Testing
|
3
5
|
module Isolation
|
4
6
|
require "thread"
|
5
7
|
|
6
|
-
def self.included(klass)
|
8
|
+
def self.included(klass) # :nodoc:
|
7
9
|
klass.class_eval do
|
8
10
|
parallelize_me!
|
9
11
|
end
|
@@ -54,14 +56,14 @@ module ActiveSupport
|
|
54
56
|
write.close
|
55
57
|
result = read.read
|
56
58
|
Process.wait2(pid)
|
57
|
-
|
59
|
+
result.unpack1("m")
|
58
60
|
end
|
59
61
|
end
|
60
62
|
|
61
63
|
module Subprocess
|
62
64
|
ORIG_ARGV = ARGV.dup unless defined?(ORIG_ARGV)
|
63
65
|
|
64
|
-
#
|
66
|
+
# Complicated H4X to get this working in windows / jruby with
|
65
67
|
# no forking.
|
66
68
|
def run_in_isolation(&blk)
|
67
69
|
require "tempfile"
|
@@ -96,7 +98,7 @@ module ActiveSupport
|
|
96
98
|
nil
|
97
99
|
end
|
98
100
|
|
99
|
-
return tmpfile.read.
|
101
|
+
return tmpfile.read.unpack1("m")
|
100
102
|
end
|
101
103
|
end
|
102
104
|
end
|
@@ -1,13 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "minitest/mock"
|
2
4
|
|
3
5
|
module ActiveSupport
|
4
6
|
module Testing
|
5
7
|
module MethodCallAssertions # :nodoc:
|
6
8
|
private
|
7
|
-
def assert_called(object, method_name, message = nil, times: 1, returns: nil)
|
9
|
+
def assert_called(object, method_name, message = nil, times: 1, returns: nil, &block)
|
8
10
|
times_called = 0
|
9
11
|
|
10
|
-
object.stub(method_name, proc { times_called += 1; returns })
|
12
|
+
object.stub(method_name, proc { times_called += 1; returns }, &block)
|
11
13
|
|
12
14
|
error = "Expected #{method_name} to be called #{times} times, " \
|
13
15
|
"but was called #{times_called} times"
|
@@ -15,16 +17,16 @@ module ActiveSupport
|
|
15
17
|
assert_equal times, times_called, error
|
16
18
|
end
|
17
19
|
|
18
|
-
def assert_called_with(object, method_name, args
|
20
|
+
def assert_called_with(object, method_name, args, returns: nil, &block)
|
19
21
|
mock = Minitest::Mock.new
|
20
22
|
|
21
|
-
if args.all?
|
23
|
+
if args.all?(Array)
|
22
24
|
args.each { |arg| mock.expect(:call, returns, arg) }
|
23
25
|
else
|
24
26
|
mock.expect(:call, returns, args)
|
25
27
|
end
|
26
28
|
|
27
|
-
object.stub(method_name, mock)
|
29
|
+
object.stub(method_name, mock, &block)
|
28
30
|
|
29
31
|
mock.verify
|
30
32
|
end
|
@@ -33,6 +35,33 @@ module ActiveSupport
|
|
33
35
|
assert_called(object, method_name, message, times: 0, &block)
|
34
36
|
end
|
35
37
|
|
38
|
+
def assert_called_on_instance_of(klass, method_name, message = nil, times: 1, returns: nil)
|
39
|
+
times_called = 0
|
40
|
+
klass.define_method("stubbed_#{method_name}") do |*|
|
41
|
+
times_called += 1
|
42
|
+
|
43
|
+
returns
|
44
|
+
end
|
45
|
+
|
46
|
+
klass.alias_method "original_#{method_name}", method_name
|
47
|
+
klass.alias_method method_name, "stubbed_#{method_name}"
|
48
|
+
|
49
|
+
yield
|
50
|
+
|
51
|
+
error = "Expected #{method_name} to be called #{times} times, but was called #{times_called} times"
|
52
|
+
error = "#{message}.\n#{error}" if message
|
53
|
+
|
54
|
+
assert_equal times, times_called, error
|
55
|
+
ensure
|
56
|
+
klass.alias_method method_name, "original_#{method_name}"
|
57
|
+
klass.undef_method "original_#{method_name}"
|
58
|
+
klass.undef_method "stubbed_#{method_name}"
|
59
|
+
end
|
60
|
+
|
61
|
+
def assert_not_called_on_instance_of(klass, method_name, message = nil, &block)
|
62
|
+
assert_called_on_instance_of(klass, method_name, message, times: 0, &block)
|
63
|
+
end
|
64
|
+
|
36
65
|
def stub_any_instance(klass, instance: klass.new)
|
37
66
|
klass.stub(:new, instance) { yield instance }
|
38
67
|
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "drb"
|
4
|
+
require "drb/unix" unless Gem.win_platform?
|
5
|
+
|
6
|
+
module ActiveSupport
|
7
|
+
module Testing
|
8
|
+
class Parallelization # :nodoc:
|
9
|
+
class Server
|
10
|
+
include DRb::DRbUndumped
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@queue = Queue.new
|
14
|
+
@active_workers = Concurrent::Map.new
|
15
|
+
@in_flight = Concurrent::Map.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def record(reporter, result)
|
19
|
+
raise DRb::DRbConnError if result.is_a?(DRb::DRbUnknown)
|
20
|
+
|
21
|
+
@in_flight.delete([result.klass, result.name])
|
22
|
+
|
23
|
+
reporter.synchronize do
|
24
|
+
reporter.record(result)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def <<(o)
|
29
|
+
o[2] = DRbObject.new(o[2]) if o
|
30
|
+
@queue << o
|
31
|
+
end
|
32
|
+
|
33
|
+
def pop
|
34
|
+
if test = @queue.pop
|
35
|
+
@in_flight[[test[0].to_s, test[1]]] = test
|
36
|
+
test
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def start_worker(worker_id)
|
41
|
+
@active_workers[worker_id] = true
|
42
|
+
end
|
43
|
+
|
44
|
+
def stop_worker(worker_id)
|
45
|
+
@active_workers.delete(worker_id)
|
46
|
+
end
|
47
|
+
|
48
|
+
def active_workers?
|
49
|
+
@active_workers.size > 0
|
50
|
+
end
|
51
|
+
|
52
|
+
def interrupt
|
53
|
+
@queue.clear
|
54
|
+
end
|
55
|
+
|
56
|
+
def shutdown
|
57
|
+
# Wait for initial queue to drain
|
58
|
+
while @queue.length != 0
|
59
|
+
sleep 0.1
|
60
|
+
end
|
61
|
+
|
62
|
+
@queue.close
|
63
|
+
|
64
|
+
# Wait until all workers have finished
|
65
|
+
while active_workers?
|
66
|
+
sleep 0.1
|
67
|
+
end
|
68
|
+
|
69
|
+
@in_flight.values.each do |(klass, name, reporter)|
|
70
|
+
result = Minitest::Result.from(klass.new(name))
|
71
|
+
error = RuntimeError.new("result not reported")
|
72
|
+
error.set_backtrace([""])
|
73
|
+
result.failures << Minitest::UnexpectedError.new(error)
|
74
|
+
reporter.synchronize do
|
75
|
+
reporter.record(result)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveSupport
|
4
|
+
module Testing
|
5
|
+
class Parallelization # :nodoc:
|
6
|
+
class Worker
|
7
|
+
def initialize(number, url)
|
8
|
+
@id = SecureRandom.uuid
|
9
|
+
@number = number
|
10
|
+
@url = url
|
11
|
+
@setup_exception = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def start
|
15
|
+
fork do
|
16
|
+
set_process_title("(starting)")
|
17
|
+
|
18
|
+
DRb.stop_service
|
19
|
+
|
20
|
+
@queue = DRbObject.new_with_uri(@url)
|
21
|
+
@queue.start_worker(@id)
|
22
|
+
|
23
|
+
begin
|
24
|
+
after_fork
|
25
|
+
rescue => @setup_exception; end
|
26
|
+
|
27
|
+
work_from_queue
|
28
|
+
ensure
|
29
|
+
set_process_title("(stopping)")
|
30
|
+
|
31
|
+
run_cleanup
|
32
|
+
@queue.stop_worker(@id)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def work_from_queue
|
37
|
+
while job = @queue.pop
|
38
|
+
perform_job(job)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def perform_job(job)
|
43
|
+
klass = job[0]
|
44
|
+
method = job[1]
|
45
|
+
reporter = job[2]
|
46
|
+
|
47
|
+
set_process_title("#{klass}##{method}")
|
48
|
+
|
49
|
+
result = klass.with_info_handler reporter do
|
50
|
+
Minitest.run_one_method(klass, method)
|
51
|
+
end
|
52
|
+
|
53
|
+
safe_record(reporter, result)
|
54
|
+
end
|
55
|
+
|
56
|
+
def safe_record(reporter, result)
|
57
|
+
add_setup_exception(result) if @setup_exception
|
58
|
+
|
59
|
+
begin
|
60
|
+
@queue.record(reporter, result)
|
61
|
+
rescue DRb::DRbConnError
|
62
|
+
result.failures.map! do |failure|
|
63
|
+
if failure.respond_to?(:error)
|
64
|
+
# minitest >5.14.0
|
65
|
+
error = DRb::DRbRemoteError.new(failure.error)
|
66
|
+
else
|
67
|
+
error = DRb::DRbRemoteError.new(failure.exception)
|
68
|
+
end
|
69
|
+
Minitest::UnexpectedError.new(error)
|
70
|
+
end
|
71
|
+
@queue.record(reporter, result)
|
72
|
+
rescue Interrupt
|
73
|
+
@queue.interrupt
|
74
|
+
raise
|
75
|
+
end
|
76
|
+
|
77
|
+
set_process_title("(idle)")
|
78
|
+
end
|
79
|
+
|
80
|
+
def after_fork
|
81
|
+
Parallelization.after_fork_hooks.each do |cb|
|
82
|
+
cb.call(@number)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def run_cleanup
|
87
|
+
Parallelization.run_cleanup_hooks.each do |cb|
|
88
|
+
cb.call(@number)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
def add_setup_exception(result)
|
94
|
+
result.failures.prepend Minitest::UnexpectedError.new(@setup_exception)
|
95
|
+
end
|
96
|
+
|
97
|
+
def set_process_title(status)
|
98
|
+
Process.setproctitle("Rails test worker #{@number} - #{status}")
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "drb"
|
4
|
+
require "drb/unix" unless Gem.win_platform?
|
5
|
+
require "active_support/core_ext/module/attribute_accessors"
|
6
|
+
require "active_support/testing/parallelization/server"
|
7
|
+
require "active_support/testing/parallelization/worker"
|
8
|
+
|
9
|
+
module ActiveSupport
|
10
|
+
module Testing
|
11
|
+
class Parallelization # :nodoc:
|
12
|
+
@@after_fork_hooks = []
|
13
|
+
|
14
|
+
def self.after_fork_hook(&blk)
|
15
|
+
@@after_fork_hooks << blk
|
16
|
+
end
|
17
|
+
|
18
|
+
cattr_reader :after_fork_hooks
|
19
|
+
|
20
|
+
@@run_cleanup_hooks = []
|
21
|
+
|
22
|
+
def self.run_cleanup_hook(&blk)
|
23
|
+
@@run_cleanup_hooks << blk
|
24
|
+
end
|
25
|
+
|
26
|
+
cattr_reader :run_cleanup_hooks
|
27
|
+
|
28
|
+
def initialize(worker_count)
|
29
|
+
@worker_count = worker_count
|
30
|
+
@queue_server = Server.new
|
31
|
+
@worker_pool = []
|
32
|
+
@url = DRb.start_service("drbunix:", @queue_server).uri
|
33
|
+
end
|
34
|
+
|
35
|
+
def start
|
36
|
+
@worker_pool = @worker_count.times.map do |worker|
|
37
|
+
Worker.new(worker, @url).start
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def <<(work)
|
42
|
+
@queue_server << work
|
43
|
+
end
|
44
|
+
|
45
|
+
def size
|
46
|
+
@worker_count
|
47
|
+
end
|
48
|
+
|
49
|
+
def shutdown
|
50
|
+
@queue_server.shutdown
|
51
|
+
@worker_pool.each { |pid| Process.waitpid pid }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveSupport
|
4
|
+
module Testing
|
5
|
+
class ParallelizeExecutor # :nodoc:
|
6
|
+
attr_reader :size, :parallelize_with, :threshold
|
7
|
+
|
8
|
+
def initialize(size:, with:, threshold: ActiveSupport.test_parallelization_threshold)
|
9
|
+
@size = size
|
10
|
+
@parallelize_with = with
|
11
|
+
@threshold = threshold
|
12
|
+
end
|
13
|
+
|
14
|
+
def start
|
15
|
+
parallelize if should_parallelize?
|
16
|
+
show_execution_info
|
17
|
+
|
18
|
+
parallel_executor.start if parallelized?
|
19
|
+
end
|
20
|
+
|
21
|
+
def <<(work)
|
22
|
+
parallel_executor << work if parallelized?
|
23
|
+
end
|
24
|
+
|
25
|
+
def shutdown
|
26
|
+
parallel_executor.shutdown if parallelized?
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
def parallel_executor
|
31
|
+
@parallel_executor ||= build_parallel_executor
|
32
|
+
end
|
33
|
+
|
34
|
+
def build_parallel_executor
|
35
|
+
case parallelize_with
|
36
|
+
when :processes
|
37
|
+
Testing::Parallelization.new(size)
|
38
|
+
when :threads
|
39
|
+
ActiveSupport::TestCase.lock_threads = false if defined?(ActiveSupport::TestCase.lock_threads)
|
40
|
+
Minitest::Parallel::Executor.new(size)
|
41
|
+
else
|
42
|
+
raise ArgumentError, "#{parallelize_with} is not a supported parallelization executor."
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def parallelize
|
47
|
+
@parallelized = true
|
48
|
+
Minitest::Test.parallelize_me!
|
49
|
+
end
|
50
|
+
|
51
|
+
def parallelized?
|
52
|
+
@parallelized if defined?(@parallelized)
|
53
|
+
end
|
54
|
+
|
55
|
+
def should_parallelize?
|
56
|
+
ENV["PARALLEL_WORKERS"] || tests_count > threshold
|
57
|
+
end
|
58
|
+
|
59
|
+
def tests_count
|
60
|
+
@tests_count ||= Minitest::Runnable.runnables.sum { |runnable| runnable.runnable_methods.size }
|
61
|
+
end
|
62
|
+
|
63
|
+
def show_execution_info
|
64
|
+
puts execution_info
|
65
|
+
end
|
66
|
+
|
67
|
+
def execution_info
|
68
|
+
if parallelized?
|
69
|
+
"Running #{tests_count} tests in parallel using #{parallel_executor.size} #{parallelize_with}"
|
70
|
+
else
|
71
|
+
"Running #{tests_count} tests in a single process (parallelization threshold is #{threshold})"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require "active_support/callbacks"
|
3
4
|
|
4
5
|
module ActiveSupport
|
@@ -17,11 +18,10 @@ module ActiveSupport
|
|
17
18
|
# end
|
18
19
|
# end
|
19
20
|
module SetupAndTeardown
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
define_callbacks :setup, :teardown
|
21
|
+
def self.prepended(klass)
|
22
|
+
klass.include ActiveSupport::Callbacks
|
23
|
+
klass.define_callbacks :setup, :teardown
|
24
|
+
klass.extend ClassMethods
|
25
25
|
end
|
26
26
|
|
27
27
|
module ClassMethods
|
@@ -42,7 +42,12 @@ module ActiveSupport
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def after_teardown # :nodoc:
|
45
|
-
|
45
|
+
begin
|
46
|
+
run_callbacks :teardown
|
47
|
+
rescue => e
|
48
|
+
self.failures << Minitest::UnexpectedError.new(e)
|
49
|
+
end
|
50
|
+
|
46
51
|
super
|
47
52
|
end
|
48
53
|
end
|
@@ -1,8 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveSupport
|
2
4
|
module Testing
|
3
|
-
module Stream
|
5
|
+
module Stream # :nodoc:
|
4
6
|
private
|
5
|
-
|
6
7
|
def silence_stream(stream)
|
7
8
|
old_stream = stream.dup
|
8
9
|
stream.reopen(IO::NULL)
|
@@ -13,11 +14,9 @@ module ActiveSupport
|
|
13
14
|
old_stream.close
|
14
15
|
end
|
15
16
|
|
16
|
-
def quietly
|
17
|
+
def quietly(&block)
|
17
18
|
silence_stream(STDOUT) do
|
18
|
-
silence_stream(STDERR)
|
19
|
-
yield
|
20
|
-
end
|
19
|
+
silence_stream(STDERR, &block)
|
21
20
|
end
|
22
21
|
end
|
23
22
|
|
@@ -31,7 +30,7 @@ module ActiveSupport
|
|
31
30
|
yield
|
32
31
|
|
33
32
|
stream_io.rewind
|
34
|
-
|
33
|
+
captured_stream.read
|
35
34
|
ensure
|
36
35
|
captured_stream.close
|
37
36
|
captured_stream.unlink
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveSupport
|
2
4
|
module Testing
|
3
5
|
# Logs a "PostsControllerTest: test name" heading before each test to
|
4
6
|
# make test.log easier to search and follow along with.
|
5
|
-
module TaggedLogging
|
7
|
+
module TaggedLogging # :nodoc:
|
6
8
|
attr_writer :tagged_logger
|
7
9
|
|
8
10
|
def before_setup
|