activesupport 5.1.7 → 6.1.7
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 +434 -490
- 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 +6 -2
- data/lib/active_support/backtrace_cleaner.rb +31 -3
- data/lib/active_support/benchmarkable.rb +3 -1
- data/lib/active_support/builder.rb +2 -0
- data/lib/active_support/cache/file_store.rb +37 -36
- data/lib/active_support/cache/mem_cache_store.rb +72 -56
- data/lib/active_support/cache/memory_store.rb +61 -33
- data/lib/active_support/cache/null_store.rb +10 -3
- data/lib/active_support/cache/redis_cache_store.rb +493 -0
- data/lib/active_support/cache/strategy/local_cache.rb +67 -21
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
- data/lib/active_support/cache.rb +310 -126
- data/lib/active_support/callbacks.rb +106 -100
- data/lib/active_support/concern.rb +79 -6
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
- data/lib/active_support/concurrency/share_lock.rb +2 -1
- data/lib/active_support/configurable.rb +12 -14
- data/lib/active_support/configuration_file.rb +51 -0
- data/lib/active_support/core_ext/array/access.rb +21 -7
- data/lib/active_support/core_ext/array/conversions.rb +7 -5
- 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 +2 -0
- data/lib/active_support/core_ext/array/inquiry.rb +2 -0
- data/lib/active_support/core_ext/array/wrap.rb +2 -0
- data/lib/active_support/core_ext/array.rb +3 -1
- data/lib/active_support/core_ext/benchmark.rb +4 -2
- data/lib/active_support/core_ext/big_decimal/conversions.rb +2 -0
- 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 +18 -40
- 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 +2 -0
- data/lib/active_support/core_ext/date/calculations.rb +8 -5
- data/lib/active_support/core_ext/date/conversions.rb +12 -10
- data/lib/active_support/core_ext/date/zones.rb +2 -0
- data/lib/active_support/core_ext/date.rb +2 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +61 -37
- 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 +2 -0
- 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 +2 -1
- data/lib/active_support/core_ext/date_time.rb +2 -0
- data/lib/active_support/core_ext/digest/uuid.rb +4 -1
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +174 -71
- data/lib/active_support/core_ext/file/atomic.rb +3 -1
- data/lib/active_support/core_ext/file.rb +2 -0
- data/lib/active_support/core_ext/hash/conversions.rb +7 -5
- 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 +2 -0
- data/lib/active_support/core_ext/hash/keys.rb +3 -30
- 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 +2 -0
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- 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/marshal.rb +4 -0
- 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 +44 -56
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +18 -18
- data/lib/active_support/core_ext/module/concerning.rb +15 -10
- data/lib/active_support/core_ext/module/delegation.rb +103 -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 +36 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +131 -129
- data/lib/active_support/core_ext/numeric/time.rb +7 -15
- data/lib/active_support/core_ext/numeric.rb +2 -1
- data/lib/active_support/core_ext/object/acts_like.rb +12 -1
- data/lib/active_support/core_ext/object/blank.rb +13 -3
- 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 +9 -114
- 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 +22 -2
- data/lib/active_support/core_ext/object/to_param.rb +2 -0
- data/lib/active_support/core_ext/object/to_query.rb +2 -0
- data/lib/active_support/core_ext/object/try.rb +19 -7
- data/lib/active_support/core_ext/object/with_options.rb +4 -2
- data/lib/active_support/core_ext/object.rb +2 -0
- data/lib/active_support/core_ext/range/compare_range.rb +82 -0
- data/lib/active_support/core_ext/range/conversions.rb +35 -25
- data/lib/active_support/core_ext/range/each.rb +5 -2
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +28 -0
- data/lib/active_support/core_ext/range/overlaps.rb +2 -0
- 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 +3 -0
- 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 +3 -0
- data/lib/active_support/core_ext/string/multibyte.rb +9 -4
- data/lib/active_support/core_ext/string/output_safety.rb +104 -20
- 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 +14 -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 +76 -18
- data/lib/active_support/core_ext/time/compatibility.rb +4 -2
- data/lib/active_support/core_ext/time/conversions.rb +4 -0
- data/lib/active_support/core_ext/time/zones.rb +6 -4
- data/lib/active_support/core_ext/time.rb +2 -0
- data/lib/active_support/core_ext/uri.rb +11 -6
- data/lib/active_support/core_ext.rb +3 -1
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +210 -0
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +2 -0
- data/lib/active_support/dependencies/zeitwerk_integration.rb +120 -0
- data/lib/active_support/dependencies.rb +134 -60
- data/lib/active_support/deprecation/behaviors.rb +43 -11
- 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 +32 -6
- data/lib/active_support/deprecation/reporting.rb +54 -9
- data/lib/active_support/deprecation.rb +9 -2
- data/lib/active_support/descendants_tracker.rb +61 -9
- data/lib/active_support/digest.rb +22 -0
- data/lib/active_support/duration/iso8601_parser.rb +6 -6
- data/lib/active_support/duration/iso8601_serializer.rb +20 -14
- data/lib/active_support/duration.rb +102 -45
- data/lib/active_support/encrypted_configuration.rb +45 -0
- data/lib/active_support/encrypted_file.rb +117 -0
- data/lib/active_support/environment_inquirer.rb +20 -0
- data/lib/active_support/evented_file_update_checker.rb +84 -117
- data/lib/active_support/execution_wrapper.rb +19 -13
- 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 +64 -0
- data/lib/active_support/gem_version.rb +3 -1
- data/lib/active_support/gzip.rb +2 -0
- data/lib/active_support/hash_with_indifferent_access.rb +123 -41
- data/lib/active_support/i18n.rb +4 -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 +19 -8
- data/lib/active_support/inflector/methods.rb +87 -77
- data/lib/active_support/inflector/transliterate.rb +56 -18
- data/lib/active_support/inflector.rb +2 -0
- data/lib/active_support/json/decoding.rb +27 -26
- data/lib/active_support/json/encoding.rb +13 -3
- data/lib/active_support/json.rb +2 -0
- data/lib/active_support/key_generator.rb +3 -33
- data/lib/active_support/lazy_load_hooks.rb +7 -2
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +7 -3
- data/lib/active_support/log_subscriber/test_helper.rb +2 -0
- data/lib/active_support/log_subscriber.rb +42 -11
- 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 +54 -7
- data/lib/active_support/message_encryptor.rb +100 -32
- data/lib/active_support/message_verifier.rb +85 -14
- 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 +12 -68
- data/lib/active_support/multibyte/unicode.rb +17 -327
- data/lib/active_support/multibyte.rb +2 -0
- data/lib/active_support/notifications/fanout.rb +118 -16
- data/lib/active_support/notifications/instrumenter.rb +73 -9
- data/lib/active_support/notifications.rb +74 -8
- data/lib/active_support/number_helper/number_converter.rb +7 -6
- data/lib/active_support/number_helper/number_to_currency_converter.rb +6 -9
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +5 -2
- 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 +6 -3
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +5 -2
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +14 -27
- data/lib/active_support/number_helper/rounding_helper.rb +16 -30
- data/lib/active_support/number_helper.rb +40 -12
- data/lib/active_support/option_merger.rb +24 -3
- data/lib/active_support/ordered_hash.rb +3 -1
- data/lib/active_support/ordered_options.rb +17 -5
- data/lib/active_support/parameter_filter.rb +133 -0
- data/lib/active_support/per_thread_registry.rb +4 -1
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +3 -10
- data/lib/active_support/railtie.rb +60 -9
- data/lib/active_support/reloader.rb +12 -11
- data/lib/active_support/rescuable.rb +7 -6
- 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 +6 -3
- data/lib/active_support/subscriber.rb +74 -24
- data/lib/active_support/tagged_logging.rb +44 -8
- data/lib/active_support/test_case.rb +94 -2
- data/lib/active_support/testing/assertions.rb +58 -20
- 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 +2 -1
- data/lib/active_support/testing/file_fixtures.rb +4 -0
- data/lib/active_support/testing/isolation.rb +4 -2
- data/lib/active_support/testing/method_call_assertions.rb +30 -1
- data/lib/active_support/testing/parallelization/server.rb +78 -0
- data/lib/active_support/testing/parallelization/worker.rb +100 -0
- data/lib/active_support/testing/parallelization.rb +51 -0
- data/lib/active_support/testing/setup_and_teardown.rb +12 -7
- data/lib/active_support/testing/stream.rb +3 -2
- data/lib/active_support/testing/tagged_logging.rb +2 -0
- data/lib/active_support/testing/time_helpers.rb +78 -13
- data/lib/active_support/time.rb +2 -0
- data/lib/active_support/time_with_zone.rb +113 -41
- data/lib/active_support/values/time_zone.rb +54 -25
- data/lib/active_support/version.rb +2 -0
- data/lib/active_support/xml_mini/jdom.rb +5 -4
- data/lib/active_support/xml_mini/libxml.rb +4 -2
- data/lib/active_support/xml_mini/libxmlsax.rb +6 -4
- data/lib/active_support/xml_mini/nokogiri.rb +4 -2
- data/lib/active_support/xml_mini/nokogirisax.rb +5 -3
- data/lib/active_support/xml_mini/rexml.rb +12 -3
- data/lib/active_support/xml_mini.rb +5 -11
- data/lib/active_support.rb +18 -13
- metadata +71 -32
- 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/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,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveSupport
|
2
4
|
module Testing
|
3
5
|
module Isolation
|
@@ -54,7 +56,7 @@ 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
|
|
@@ -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,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "minitest/mock"
|
2
4
|
|
3
5
|
module ActiveSupport
|
@@ -15,7 +17,7 @@ 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)
|
19
21
|
mock = Minitest::Mock.new
|
20
22
|
|
21
23
|
if args.all? { |arg| arg.is_a?(Array) }
|
@@ -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,78 @@
|
|
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 shutdown
|
53
|
+
# Wait for initial queue to drain
|
54
|
+
while @queue.length != 0
|
55
|
+
sleep 0.1
|
56
|
+
end
|
57
|
+
|
58
|
+
@queue.close
|
59
|
+
|
60
|
+
# Wait until all workers have finished
|
61
|
+
while active_workers?
|
62
|
+
sleep 0.1
|
63
|
+
end
|
64
|
+
|
65
|
+
@in_flight.values.each do |(klass, name, reporter)|
|
66
|
+
result = Minitest::Result.from(klass.new(name))
|
67
|
+
error = RuntimeError.new("result not reported")
|
68
|
+
error.set_backtrace([""])
|
69
|
+
result.failures << Minitest::UnexpectedError.new(error)
|
70
|
+
reporter.synchronize do
|
71
|
+
reporter.record(result)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,100 @@
|
|
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
|
+
end
|
73
|
+
|
74
|
+
set_process_title("(idle)")
|
75
|
+
end
|
76
|
+
|
77
|
+
def after_fork
|
78
|
+
Parallelization.after_fork_hooks.each do |cb|
|
79
|
+
cb.call(@number)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def run_cleanup
|
84
|
+
Parallelization.run_cleanup_hooks.each do |cb|
|
85
|
+
cb.call(@number)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
def add_setup_exception(result)
|
91
|
+
result.failures.prepend Minitest::UnexpectedError.new(@setup_exception)
|
92
|
+
end
|
93
|
+
|
94
|
+
def set_process_title(status)
|
95
|
+
Process.setproctitle("Rails test worker #{@number} - #{status}")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,51 @@
|
|
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 shutdown
|
46
|
+
@queue_server.shutdown
|
47
|
+
@worker_pool.each { |pid| Process.waitpid pid }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
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
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)
|
@@ -31,7 +32,7 @@ module ActiveSupport
|
|
31
32
|
yield
|
32
33
|
|
33
34
|
stream_io.rewind
|
34
|
-
|
35
|
+
captured_stream.read
|
35
36
|
ensure
|
36
37
|
captured_stream.close
|
37
38
|
captured_stream.unlink
|
@@ -1,9 +1,12 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/module/redefine_method"
|
2
4
|
require "active_support/core_ext/time/calculations"
|
3
5
|
require "concurrent/map"
|
4
6
|
|
5
7
|
module ActiveSupport
|
6
8
|
module Testing
|
9
|
+
# Manages stubs for TimeHelpers
|
7
10
|
class SimpleStubs # :nodoc:
|
8
11
|
Stub = Struct.new(:object, :method_name, :original_method)
|
9
12
|
|
@@ -11,6 +14,13 @@ module ActiveSupport
|
|
11
14
|
@stubs = Concurrent::Map.new { |h, k| h[k] = {} }
|
12
15
|
end
|
13
16
|
|
17
|
+
# Stubs object.method_name with the given block
|
18
|
+
# If the method is already stubbed, remove that stub
|
19
|
+
# so that removing this stub will restore the original implementation.
|
20
|
+
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
21
|
+
# target = Time.zone.local(2004, 11, 24, 1, 4, 44)
|
22
|
+
# simple_stubs.stub_object(Time, :now) { at(target.to_i) }
|
23
|
+
# Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
|
14
24
|
def stub_object(object, method_name, &block)
|
15
25
|
if stub = stubbing(object, method_name)
|
16
26
|
unstub_object(stub)
|
@@ -20,10 +30,11 @@ module ActiveSupport
|
|
20
30
|
|
21
31
|
@stubs[object.object_id][method_name] = Stub.new(object, method_name, new_name)
|
22
32
|
|
23
|
-
object.singleton_class.
|
33
|
+
object.singleton_class.alias_method new_name, method_name
|
24
34
|
object.define_singleton_method(method_name, &block)
|
25
35
|
end
|
26
36
|
|
37
|
+
# Remove all object-method stubs held by this instance
|
27
38
|
def unstub_all!
|
28
39
|
@stubs.each_value do |object_stubs|
|
29
40
|
object_stubs.each_value do |stub|
|
@@ -33,24 +44,37 @@ module ActiveSupport
|
|
33
44
|
@stubs.clear
|
34
45
|
end
|
35
46
|
|
47
|
+
# Returns the Stub for object#method_name
|
48
|
+
# (nil if it is not stubbed)
|
36
49
|
def stubbing(object, method_name)
|
37
50
|
@stubs[object.object_id][method_name]
|
38
51
|
end
|
39
52
|
|
40
|
-
|
53
|
+
# Returns true if any stubs are set, false if there are none
|
54
|
+
def stubbed?
|
55
|
+
!@stubs.empty?
|
56
|
+
end
|
41
57
|
|
58
|
+
private
|
59
|
+
# Restores the original object.method described by the Stub
|
42
60
|
def unstub_object(stub)
|
43
61
|
singleton_class = stub.object.singleton_class
|
44
|
-
singleton_class.
|
45
|
-
singleton_class.
|
46
|
-
singleton_class.
|
62
|
+
singleton_class.silence_redefinition_of_method stub.method_name
|
63
|
+
singleton_class.alias_method stub.method_name, stub.original_method
|
64
|
+
singleton_class.undef_method stub.original_method
|
47
65
|
end
|
48
66
|
end
|
49
67
|
|
50
68
|
# Contains helpers that help you test passage of time.
|
51
69
|
module TimeHelpers
|
70
|
+
def after_teardown
|
71
|
+
travel_back
|
72
|
+
super
|
73
|
+
end
|
74
|
+
|
52
75
|
# Changes current time to the time in the future or in the past by a given time difference by
|
53
|
-
# stubbing +Time.now+, +Date.today+, and +DateTime.now+.
|
76
|
+
# stubbing +Time.now+, +Date.today+, and +DateTime.now+. The stubs are automatically removed
|
77
|
+
# at the end of the test.
|
54
78
|
#
|
55
79
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
56
80
|
# travel 1.day
|
@@ -72,9 +96,10 @@ module ActiveSupport
|
|
72
96
|
|
73
97
|
# Changes current time to the given time by stubbing +Time.now+,
|
74
98
|
# +Date.today+, and +DateTime.now+ to return the time or date passed into this method.
|
99
|
+
# The stubs are automatically removed at the end of the test.
|
75
100
|
#
|
76
101
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
77
|
-
# travel_to Time.zone.local(2004, 11, 24,
|
102
|
+
# travel_to Time.zone.local(2004, 11, 24, 1, 4, 44)
|
78
103
|
# Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
|
79
104
|
# Date.current # => Wed, 24 Nov 2004
|
80
105
|
# DateTime.current # => Wed, 24 Nov 2004 01:04:44 -0500
|
@@ -96,13 +121,13 @@ module ActiveSupport
|
|
96
121
|
# state at the end of the block:
|
97
122
|
#
|
98
123
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
99
|
-
# travel_to Time.zone.local(2004, 11, 24,
|
124
|
+
# travel_to Time.zone.local(2004, 11, 24, 1, 4, 44) do
|
100
125
|
# Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
|
101
126
|
# end
|
102
127
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
103
128
|
def travel_to(date_or_time)
|
104
129
|
if block_given? && simple_stubs.stubbing(Time, :now)
|
105
|
-
travel_to_nested_block_call =
|
130
|
+
travel_to_nested_block_call = <<~MSG
|
106
131
|
|
107
132
|
Calling `travel_to` with a block, when we have previously already made a call to `travel_to`, can lead to confusing time stubbing.
|
108
133
|
|
@@ -149,19 +174,59 @@ module ActiveSupport
|
|
149
174
|
end
|
150
175
|
|
151
176
|
# Returns the current time back to its original state, by removing the stubs added by
|
152
|
-
#
|
177
|
+
# +travel+, +travel_to+, and +freeze_time+.
|
153
178
|
#
|
154
179
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
155
|
-
#
|
180
|
+
#
|
181
|
+
# travel_to Time.zone.local(2004, 11, 24, 1, 4, 44)
|
156
182
|
# Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
|
183
|
+
#
|
157
184
|
# travel_back
|
158
185
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
186
|
+
#
|
187
|
+
# This method also accepts a block, which brings the stubs back at the end of the block:
|
188
|
+
#
|
189
|
+
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
190
|
+
#
|
191
|
+
# travel_to Time.zone.local(2004, 11, 24, 1, 4, 44)
|
192
|
+
# Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
|
193
|
+
#
|
194
|
+
# travel_back do
|
195
|
+
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
196
|
+
# end
|
197
|
+
#
|
198
|
+
# Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
|
159
199
|
def travel_back
|
200
|
+
stubbed_time = Time.current if block_given? && simple_stubs.stubbed?
|
201
|
+
|
160
202
|
simple_stubs.unstub_all!
|
203
|
+
yield if block_given?
|
204
|
+
ensure
|
205
|
+
travel_to stubbed_time if stubbed_time
|
161
206
|
end
|
207
|
+
alias_method :unfreeze_time, :travel_back
|
162
208
|
|
163
|
-
|
209
|
+
# Calls +travel_to+ with +Time.now+.
|
210
|
+
#
|
211
|
+
# Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00
|
212
|
+
# freeze_time
|
213
|
+
# sleep(1)
|
214
|
+
# Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00
|
215
|
+
#
|
216
|
+
# This method also accepts a block, which will return the current time back to its original
|
217
|
+
# state at the end of the block:
|
218
|
+
#
|
219
|
+
# Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00
|
220
|
+
# freeze_time do
|
221
|
+
# sleep(1)
|
222
|
+
# User.create.created_at # => Sun, 09 Jul 2017 15:34:49 EST -05:00
|
223
|
+
# end
|
224
|
+
# Time.current # => Sun, 09 Jul 2017 15:34:50 EST -05:00
|
225
|
+
def freeze_time(&block)
|
226
|
+
travel_to Time.now, &block
|
227
|
+
end
|
164
228
|
|
229
|
+
private
|
165
230
|
def simple_stubs
|
166
231
|
@simple_stubs ||= SimpleStubs.new
|
167
232
|
end
|