activesupport 7.0.8.7 → 7.2.2.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 +143 -459
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -4
- 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 +251 -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 +49 -17
- data/lib/active_support/cache/mem_cache_store.rb +94 -128
- data/lib/active_support/cache/memory_store.rb +80 -25
- data/lib/active_support/cache/null_store.rb +6 -0
- data/lib/active_support/cache/redis_cache_store.rb +165 -152
- data/lib/active_support/cache/serializer_with_fallback.rb +152 -0
- data/lib/active_support/cache/strategy/local_cache.rb +29 -14
- data/lib/active_support/cache.rb +363 -291
- data/lib/active_support/callbacks.rb +118 -134
- 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/class/subclasses.rb +17 -34
- data/lib/active_support/core_ext/date/blank.rb +4 -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/conversions.rb +2 -2
- 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 +3 -75
- 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/keys.rb +4 -4
- 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 +0 -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/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/with.rb +46 -0
- data/lib/active_support/core_ext/object/with_options.rb +4 -4
- 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.rb +1 -2
- data/lib/active_support/core_ext/securerandom.rb +1 -5
- data/lib/active_support/core_ext/string/conversions.rb +1 -1
- data/lib/active_support/core_ext/string/filters.rb +21 -15
- data/lib/active_support/core_ext/string/indent.rb +1 -1
- data/lib/active_support/core_ext/string/inflections.rb +16 -5
- data/lib/active_support/core_ext/string/multibyte.rb +1 -1
- data/lib/active_support/core_ext/string/output_safety.rb +34 -177
- data/lib/active_support/core_ext/thread/backtrace/location.rb +12 -0
- data/lib/active_support/core_ext/time/calculations.rb +36 -30
- data/lib/active_support/core_ext/time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/time/conversions.rb +1 -3
- data/lib/active_support/core_ext/time/zones.rb +4 -4
- 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 +53 -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 +65 -42
- 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 +3 -5
- 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 +30 -9
- data/lib/active_support/encrypted_file.rb +9 -4
- 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 +160 -36
- data/lib/active_support/evented_file_update_checker.rb +0 -1
- data/lib/active_support/execution_wrapper.rb +4 -5
- data/lib/active_support/file_update_checker.rb +5 -3
- data/lib/active_support/fork_tracker.rb +4 -32
- data/lib/active_support/gem_version.rb +4 -4
- data/lib/active_support/gzip.rb +2 -0
- data/lib/active_support/hash_with_indifferent_access.rb +41 -25
- 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 +23 -11
- 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 +2 -1
- data/lib/active_support/json/encoding.rb +25 -43
- data/lib/active_support/key_generator.rb +9 -1
- data/lib/active_support/lazy_load_hooks.rb +6 -4
- 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 -60
- 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 +220 -89
- data/lib/active_support/message_verifiers.rb +135 -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 +34 -32
- data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
- data/lib/active_support/multibyte/chars.rb +4 -2
- 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 +29 -28
- 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_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 -318
- data/lib/active_support/option_merger.rb +2 -2
- 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 +84 -69
- 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 +2 -0
- 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 -25
- data/lib/active_support/test_case.rb +156 -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 +21 -9
- data/lib/active_support/testing/method_call_assertions.rb +7 -8
- data/lib/active_support/testing/parallelization/server.rb +3 -0
- 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/strict_warnings.rb +43 -0
- 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 +12 -18
- 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 +12 -3
- data/lib/active_support.rb +15 -3
- metadata +140 -19
- data/lib/active_support/core_ext/array/deprecated_conversions.rb +0 -25
- data/lib/active_support/core_ext/date/deprecated_conversions.rb +0 -40
- data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +0 -36
- data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +0 -60
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +0 -36
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +0 -5
- data/lib/active_support/core_ext/range/overlaps.rb +0 -10
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +0 -73
- 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
@@ -0,0 +1,107 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveSupport
|
4
|
+
module Testing
|
5
|
+
module ErrorReporterAssertions
|
6
|
+
module ErrorCollector # :nodoc:
|
7
|
+
@subscribed = false
|
8
|
+
@mutex = Mutex.new
|
9
|
+
|
10
|
+
Report = Struct.new(:error, :handled, :severity, :context, :source, keyword_init: true)
|
11
|
+
class Report
|
12
|
+
alias_method :handled?, :handled
|
13
|
+
end
|
14
|
+
|
15
|
+
class << self
|
16
|
+
def record
|
17
|
+
subscribe
|
18
|
+
recorders = ActiveSupport::IsolatedExecutionState[:active_support_error_reporter_assertions] ||= []
|
19
|
+
reports = []
|
20
|
+
recorders << reports
|
21
|
+
begin
|
22
|
+
yield
|
23
|
+
reports
|
24
|
+
ensure
|
25
|
+
recorders.delete_if { |r| reports.equal?(r) }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def report(error, **kwargs)
|
30
|
+
report = Report.new(error: error, **kwargs)
|
31
|
+
ActiveSupport::IsolatedExecutionState[:active_support_error_reporter_assertions]&.each do |reports|
|
32
|
+
reports << report
|
33
|
+
end
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
def subscribe
|
39
|
+
return if @subscribed
|
40
|
+
@mutex.synchronize do
|
41
|
+
return if @subscribed
|
42
|
+
|
43
|
+
if ActiveSupport.error_reporter
|
44
|
+
ActiveSupport.error_reporter.subscribe(self)
|
45
|
+
@subscribed = true
|
46
|
+
else
|
47
|
+
raise Minitest::Assertion, "No error reporter is configured"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Assertion that the block should not cause an exception to be reported
|
55
|
+
# to +Rails.error+.
|
56
|
+
#
|
57
|
+
# Passes if evaluated code in the yielded block reports no exception.
|
58
|
+
#
|
59
|
+
# assert_no_error_reported do
|
60
|
+
# perform_service(param: 'no_exception')
|
61
|
+
# end
|
62
|
+
def assert_no_error_reported(&block)
|
63
|
+
reports = ErrorCollector.record do
|
64
|
+
_assert_nothing_raised_or_warn("assert_no_error_reported", &block)
|
65
|
+
end
|
66
|
+
assert_predicate(reports, :empty?)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Assertion that the block should cause at least one exception to be reported
|
70
|
+
# to +Rails.error+.
|
71
|
+
#
|
72
|
+
# Passes if the evaluated code in the yielded block reports a matching exception.
|
73
|
+
#
|
74
|
+
# assert_error_reported(IOError) do
|
75
|
+
# Rails.error.report(IOError.new("Oops"))
|
76
|
+
# end
|
77
|
+
#
|
78
|
+
# To test further details about the reported exception, you can use the return
|
79
|
+
# value.
|
80
|
+
#
|
81
|
+
# report = assert_error_reported(IOError) do
|
82
|
+
# # ...
|
83
|
+
# end
|
84
|
+
# assert_equal "Oops", report.error.message
|
85
|
+
# assert_equal "admin", report.context[:section]
|
86
|
+
# assert_equal :warning, report.severity
|
87
|
+
# assert_predicate report, :handled?
|
88
|
+
def assert_error_reported(error_class = StandardError, &block)
|
89
|
+
reports = ErrorCollector.record do
|
90
|
+
_assert_nothing_raised_or_warn("assert_error_reported", &block)
|
91
|
+
end
|
92
|
+
|
93
|
+
if reports.empty?
|
94
|
+
assert(false, "Expected a #{error_class.name} to be reported, but there were no errors reported.")
|
95
|
+
elsif (report = reports.find { |r| error_class === r.error })
|
96
|
+
self.assertions += 1
|
97
|
+
report
|
98
|
+
else
|
99
|
+
message = "Expected a #{error_class.name} to be reported, but none of the " \
|
100
|
+
"#{reports.size} reported errors matched: \n" \
|
101
|
+
"#{reports.map { |r| r.error.class.name }.join("\n ")}"
|
102
|
+
assert(false, message)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -1,13 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "active_support/testing/parallelize_executor"
|
4
|
+
|
3
5
|
module ActiveSupport
|
4
6
|
module Testing
|
5
7
|
module Isolation
|
6
8
|
require "thread"
|
7
9
|
|
10
|
+
SubprocessCrashed = Class.new(StandardError)
|
11
|
+
|
8
12
|
def self.included(klass) # :nodoc:
|
9
13
|
klass.class_eval do
|
10
|
-
parallelize_me!
|
14
|
+
parallelize_me! unless Minitest.parallel_executor.is_a?(ActiveSupport::Testing::ParallelizeExecutor)
|
11
15
|
end
|
12
16
|
end
|
13
17
|
|
@@ -16,10 +20,17 @@ module ActiveSupport
|
|
16
20
|
end
|
17
21
|
|
18
22
|
def run
|
19
|
-
serialized = run_in_isolation do
|
23
|
+
status, serialized = run_in_isolation do
|
20
24
|
super
|
21
25
|
end
|
22
26
|
|
27
|
+
unless status&.success?
|
28
|
+
error = SubprocessCrashed.new("Subprocess exited with an error: #{status.inspect}\noutput: #{serialized.inspect}")
|
29
|
+
error.set_backtrace(caller)
|
30
|
+
self.failures << Minitest::UnexpectedError.new(error)
|
31
|
+
return defined?(Minitest::Result) ? Minitest::Result.from(self) : dup
|
32
|
+
end
|
33
|
+
|
23
34
|
Marshal.load(serialized)
|
24
35
|
end
|
25
36
|
|
@@ -50,13 +61,13 @@ module ActiveSupport
|
|
50
61
|
end
|
51
62
|
|
52
63
|
write.puts [result].pack("m")
|
53
|
-
exit!
|
64
|
+
exit!(0)
|
54
65
|
end
|
55
66
|
|
56
67
|
write.close
|
57
68
|
result = read.read
|
58
|
-
Process.wait2(pid)
|
59
|
-
result.unpack1("m")
|
69
|
+
_, status = Process.wait2(pid)
|
70
|
+
return status, result.unpack1("m")
|
60
71
|
end
|
61
72
|
end
|
62
73
|
end
|
@@ -64,7 +75,7 @@ module ActiveSupport
|
|
64
75
|
module Subprocess
|
65
76
|
ORIG_ARGV = ARGV.dup unless defined?(ORIG_ARGV)
|
66
77
|
|
67
|
-
# Complicated H4X to get this working in
|
78
|
+
# Complicated H4X to get this working in Windows / JRuby with
|
68
79
|
# no forking.
|
69
80
|
def run_in_isolation(&blk)
|
70
81
|
require "tempfile"
|
@@ -75,7 +86,7 @@ module ActiveSupport
|
|
75
86
|
File.open(ENV["ISOLATION_OUTPUT"], "w") do |file|
|
76
87
|
file.puts [Marshal.dump(test_result)].pack("m")
|
77
88
|
end
|
78
|
-
exit!
|
89
|
+
exit!(0)
|
79
90
|
else
|
80
91
|
Tempfile.open("isolation") do |tmpfile|
|
81
92
|
env = {
|
@@ -93,13 +104,14 @@ module ActiveSupport
|
|
93
104
|
|
94
105
|
child = IO.popen([env, Gem.ruby, *load_path_args, $0, *ORIG_ARGV, test_opts])
|
95
106
|
|
107
|
+
status = nil
|
96
108
|
begin
|
97
|
-
Process.
|
109
|
+
_, status = Process.wait2(child.pid)
|
98
110
|
rescue Errno::ECHILD # The child process may exit before we wait
|
99
111
|
nil
|
100
112
|
end
|
101
113
|
|
102
|
-
return tmpfile.read.unpack1("m")
|
114
|
+
return status, tmpfile.read.unpack1("m")
|
103
115
|
end
|
104
116
|
end
|
105
117
|
end
|
@@ -17,24 +17,23 @@ module ActiveSupport
|
|
17
17
|
assert_equal times, times_called, error
|
18
18
|
end
|
19
19
|
|
20
|
-
def assert_called_with(object, method_name, args, returns:
|
20
|
+
def assert_called_with(object, method_name, args, returns: false, **kwargs, &block)
|
21
21
|
mock = Minitest::Mock.new
|
22
|
-
|
23
|
-
if args.all?(Array)
|
24
|
-
args.each { |arg| mock.expect(:call, returns, arg) }
|
25
|
-
else
|
26
|
-
mock.expect(:call, returns, args)
|
27
|
-
end
|
22
|
+
expect_called_with(mock, args, returns: returns, **kwargs)
|
28
23
|
|
29
24
|
object.stub(method_name, mock, &block)
|
30
25
|
|
31
|
-
mock
|
26
|
+
assert_mock(mock)
|
32
27
|
end
|
33
28
|
|
34
29
|
def assert_not_called(object, method_name, message = nil, &block)
|
35
30
|
assert_called(object, method_name, message, times: 0, &block)
|
36
31
|
end
|
37
32
|
|
33
|
+
def expect_called_with(mock, args, returns: false, **kwargs)
|
34
|
+
mock.expect(:call, returns, args, **kwargs)
|
35
|
+
end
|
36
|
+
|
38
37
|
def assert_called_on_instance_of(klass, method_name, message = nil, times: 1, returns: nil)
|
39
38
|
times_called = 0
|
40
39
|
klass.define_method("stubbed_#{method_name}") do |*|
|
@@ -6,6 +6,8 @@ require "drb/unix" unless Gem.win_platform?
|
|
6
6
|
module ActiveSupport
|
7
7
|
module Testing
|
8
8
|
class Parallelization # :nodoc:
|
9
|
+
PrerecordResultClass = Struct.new(:name)
|
10
|
+
|
9
11
|
class Server
|
10
12
|
include DRb::DRbUndumped
|
11
13
|
|
@@ -21,6 +23,7 @@ module ActiveSupport
|
|
21
23
|
@in_flight.delete([result.klass, result.name])
|
22
24
|
|
23
25
|
reporter.synchronize do
|
26
|
+
reporter.prerecord(PrerecordResultClass.new(result.klass), result.name)
|
24
27
|
reporter.record(result)
|
25
28
|
end
|
26
29
|
end
|
@@ -9,6 +9,7 @@ module ActiveSupport
|
|
9
9
|
@size = size
|
10
10
|
@parallelize_with = with
|
11
11
|
@threshold = threshold
|
12
|
+
@parallelized = false
|
12
13
|
end
|
13
14
|
|
14
15
|
def start
|
@@ -49,11 +50,15 @@ module ActiveSupport
|
|
49
50
|
end
|
50
51
|
|
51
52
|
def parallelized?
|
52
|
-
@parallelized
|
53
|
+
@parallelized
|
53
54
|
end
|
54
55
|
|
55
56
|
def should_parallelize?
|
56
|
-
ENV["PARALLEL_WORKERS"] || tests_count > threshold
|
57
|
+
(ENV["PARALLEL_WORKERS"] || tests_count > threshold) && many_workers?
|
58
|
+
end
|
59
|
+
|
60
|
+
def many_workers?
|
61
|
+
size > 1
|
57
62
|
end
|
58
63
|
|
59
64
|
def tests_count
|
@@ -67,7 +72,7 @@ module ActiveSupport
|
|
67
72
|
def execution_info
|
68
73
|
if parallelized?
|
69
74
|
"Running #{tests_count} tests in parallel using #{parallel_executor.size} #{parallelize_with}"
|
70
|
-
|
75
|
+
elsif many_workers?
|
71
76
|
"Running #{tests_count} tests in a single process (parallelization threshold is #{threshold})"
|
72
77
|
end
|
73
78
|
end
|
@@ -23,7 +23,7 @@ module ActiveSupport
|
|
23
23
|
def capture(stream)
|
24
24
|
stream = stream.to_s
|
25
25
|
captured_stream = Tempfile.new(stream)
|
26
|
-
stream_io = eval("$#{stream}")
|
26
|
+
stream_io = eval("$#{stream}", binding, __FILE__, __LINE__)
|
27
27
|
origin_stream = stream_io.dup
|
28
28
|
stream_io.reopen(captured_stream)
|
29
29
|
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
$VERBOSE = true
|
4
|
+
Warning[:deprecated] = true
|
5
|
+
|
6
|
+
module ActiveSupport
|
7
|
+
module RaiseWarnings # :nodoc:
|
8
|
+
class WarningError < StandardError; end
|
9
|
+
|
10
|
+
PROJECT_ROOT = File.expand_path("../../../../", __dir__)
|
11
|
+
ALLOWED_WARNINGS = Regexp.union(
|
12
|
+
/circular require considered harmful.*delayed_job/, # Bug in delayed job.
|
13
|
+
|
14
|
+
# Expected non-verbose warning emitted by Rails.
|
15
|
+
/Ignoring .*\.yml because it has expired/,
|
16
|
+
/Failed to validate the schema cache because/,
|
17
|
+
|
18
|
+
# TODO: We need to decide what to do with this.
|
19
|
+
/Status code :unprocessable_entity is deprecated/
|
20
|
+
)
|
21
|
+
|
22
|
+
SUPPRESSED_WARNINGS = Regexp.union(
|
23
|
+
# TODO: remove if https://github.com/mikel/mail/pull/1557 or similar fix
|
24
|
+
%r{/lib/mail/parsers/.*statement not reached},
|
25
|
+
%r{/lib/mail/parsers/.*assigned but unused variable - disp_type_s},
|
26
|
+
%r{/lib/mail/parsers/.*assigned but unused variable - testEof}
|
27
|
+
)
|
28
|
+
|
29
|
+
def warn(message, ...)
|
30
|
+
return if SUPPRESSED_WARNINGS.match?(message)
|
31
|
+
|
32
|
+
super
|
33
|
+
|
34
|
+
return unless message.include?(PROJECT_ROOT)
|
35
|
+
return if ALLOWED_WARNINGS.match?(message)
|
36
|
+
return unless ENV["RAILS_STRICT_WARNINGS"] || ENV["BUILDKITE"]
|
37
|
+
|
38
|
+
raise WarningError.new(message)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
Warning.singleton_class.prepend(ActiveSupport::RaiseWarnings)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveSupport
|
4
|
+
module Testing
|
5
|
+
# Warns when a test case does not perform any assertions.
|
6
|
+
#
|
7
|
+
# This is helpful in detecting broken tests that do not perform intended assertions.
|
8
|
+
module TestsWithoutAssertions # :nodoc:
|
9
|
+
def after_teardown
|
10
|
+
super
|
11
|
+
|
12
|
+
if assertions.zero? && !skipped? && !error?
|
13
|
+
file, line = method(name).source_location
|
14
|
+
warn "Test is missing assertions: `#{name}` #{file}:#{line}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
require "active_support/core_ext/module/redefine_method"
|
4
4
|
require "active_support/core_ext/time/calculations"
|
5
|
-
require "concurrent/map"
|
6
5
|
|
7
6
|
module ActiveSupport
|
8
7
|
module Testing
|
@@ -11,7 +10,7 @@ module ActiveSupport
|
|
11
10
|
Stub = Struct.new(:object, :method_name, :original_method)
|
12
11
|
|
13
12
|
def initialize
|
14
|
-
@stubs =
|
13
|
+
@stubs = Hash.new { |h, k| h[k] = {} }
|
15
14
|
end
|
16
15
|
|
17
16
|
# Stubs object.method_name with the given block
|
@@ -26,7 +25,7 @@ module ActiveSupport
|
|
26
25
|
unstub_object(stub)
|
27
26
|
end
|
28
27
|
|
29
|
-
new_name = "__simple_stub__#{method_name}"
|
28
|
+
new_name = "__simple_stub__#{method_name}__#{object_id}"
|
30
29
|
|
31
30
|
@stubs[object.object_id][method_name] = Stub.new(object, method_name, new_name)
|
32
31
|
|
@@ -76,6 +75,11 @@ module ActiveSupport
|
|
76
75
|
# stubbing +Time.now+, +Date.today+, and +DateTime.now+. The stubs are automatically removed
|
77
76
|
# at the end of the test.
|
78
77
|
#
|
78
|
+
# Note that the usec for the resulting time will be set to 0 to prevent rounding
|
79
|
+
# errors with external services, like MySQL (which will round instead of floor,
|
80
|
+
# leading to off-by-one-second errors), unless the <tt>with_usec</tt> argument
|
81
|
+
# is set to <tt>true</tt>.
|
82
|
+
#
|
79
83
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
80
84
|
# travel 1.day
|
81
85
|
# Time.current # => Sun, 10 Nov 2013 15:34:49 EST -05:00
|
@@ -90,11 +94,11 @@ module ActiveSupport
|
|
90
94
|
# User.create.created_at # => Sun, 10 Nov 2013 15:34:49 EST -05:00
|
91
95
|
# end
|
92
96
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
93
|
-
def travel(duration, &block)
|
94
|
-
travel_to Time.now + duration, &block
|
97
|
+
def travel(duration, with_usec: false, &block)
|
98
|
+
travel_to Time.now + duration, with_usec: with_usec, &block
|
95
99
|
end
|
96
100
|
|
97
|
-
# Changes current time to the given time by stubbing +Time.now+,
|
101
|
+
# Changes current time to the given time by stubbing +Time.now+, +Time.new+,
|
98
102
|
# +Date.today+, and +DateTime.now+ to return the time or date passed into this method.
|
99
103
|
# The stubs are automatically removed at the end of the test.
|
100
104
|
#
|
@@ -115,7 +119,8 @@ module ActiveSupport
|
|
115
119
|
#
|
116
120
|
# Note that the usec for the time passed will be set to 0 to prevent rounding
|
117
121
|
# errors with external services, like MySQL (which will round instead of floor,
|
118
|
-
# leading to off-by-one-second errors)
|
122
|
+
# leading to off-by-one-second errors), unless the <tt>with_usec</tt> argument
|
123
|
+
# is set to <tt>true</tt>.
|
119
124
|
#
|
120
125
|
# This method also accepts a block, which will return the current time back to its original
|
121
126
|
# state at the end of the block:
|
@@ -125,7 +130,7 @@ module ActiveSupport
|
|
125
130
|
# Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
|
126
131
|
# end
|
127
132
|
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
|
128
|
-
def travel_to(date_or_time)
|
133
|
+
def travel_to(date_or_time, with_usec: false)
|
129
134
|
if block_given? && in_block
|
130
135
|
travel_to_nested_block_call = <<~MSG
|
131
136
|
|
@@ -159,13 +164,30 @@ module ActiveSupport
|
|
159
164
|
elsif date_or_time.is_a?(String)
|
160
165
|
now = Time.zone.parse(date_or_time)
|
161
166
|
else
|
162
|
-
now = date_or_time
|
167
|
+
now = date_or_time
|
168
|
+
now = now.to_time unless now.is_a?(Time)
|
169
|
+
now = now.change(usec: 0) unless with_usec
|
170
|
+
end
|
171
|
+
|
172
|
+
# +now+ must be in local system timezone, because +Time.at(now)+
|
173
|
+
# and +now.to_date+ (see stubs below) will use +now+'s timezone too!
|
174
|
+
now = now.getlocal
|
175
|
+
|
176
|
+
stubs = simple_stubs
|
177
|
+
stubbed_time = Time.now if stubs.stubbing(Time, :now)
|
178
|
+
stubs.stub_object(Time, :now) { at(now) }
|
179
|
+
|
180
|
+
stubs.stub_object(Time, :new) do |*args, **options|
|
181
|
+
if args.empty? && options.empty?
|
182
|
+
at(now)
|
183
|
+
else
|
184
|
+
stub = stubs.stubbing(Time, :new)
|
185
|
+
Time.send(stub.original_method, *args, **options)
|
186
|
+
end
|
163
187
|
end
|
164
188
|
|
165
|
-
|
166
|
-
|
167
|
-
simple_stubs.stub_object(Date, :today) { jd(now.to_date.jd) }
|
168
|
-
simple_stubs.stub_object(DateTime, :now) { jd(now.to_date.jd, now.hour, now.min, now.sec, Rational(now.utc_offset, 86400)) }
|
189
|
+
stubs.stub_object(Date, :today) { jd(now.to_date.jd) }
|
190
|
+
stubs.stub_object(DateTime, :now) { jd(now.to_date.jd, now.hour, now.min, now.sec, Rational(now.utc_offset, 86400)) }
|
169
191
|
|
170
192
|
if block_given?
|
171
193
|
begin
|
@@ -215,7 +237,7 @@ module ActiveSupport
|
|
215
237
|
end
|
216
238
|
alias_method :unfreeze_time, :travel_back
|
217
239
|
|
218
|
-
# Calls +travel_to+ with +Time.now+.
|
240
|
+
# Calls +travel_to+ with +Time.now+. Forwards optional <tt>with_usec</tt> argument.
|
219
241
|
#
|
220
242
|
# Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00
|
221
243
|
# freeze_time
|
@@ -231,8 +253,8 @@ module ActiveSupport
|
|
231
253
|
# User.create.created_at # => Sun, 09 Jul 2017 15:34:49 EST -05:00
|
232
254
|
# end
|
233
255
|
# Time.current # => Sun, 09 Jul 2017 15:34:50 EST -05:00
|
234
|
-
def freeze_time(&block)
|
235
|
-
travel_to Time.now, &block
|
256
|
+
def freeze_time(with_usec: false, &block)
|
257
|
+
travel_to Time.now, with_usec: with_usec, &block
|
236
258
|
end
|
237
259
|
|
238
260
|
private
|
@@ -8,6 +8,8 @@ require "active_support/core_ext/object/acts_like"
|
|
8
8
|
require "active_support/core_ext/date_and_time/compatibility"
|
9
9
|
|
10
10
|
module ActiveSupport
|
11
|
+
# = Active Support \Time With Zone
|
12
|
+
#
|
11
13
|
# A Time-like class that can represent a time in any time zone. Necessary
|
12
14
|
# because standard Ruby Time instances are limited to UTC and the
|
13
15
|
# system's <tt>ENV['TZ']</tt> zone.
|
@@ -40,18 +42,6 @@ module ActiveSupport
|
|
40
42
|
# t.is_a?(Time) # => true
|
41
43
|
# t.is_a?(ActiveSupport::TimeWithZone) # => true
|
42
44
|
class TimeWithZone
|
43
|
-
# Report class name as 'Time' to thwart type checking.
|
44
|
-
def self.name
|
45
|
-
ActiveSupport::Deprecation.warn(<<~EOM)
|
46
|
-
ActiveSupport::TimeWithZone.name has been deprecated and
|
47
|
-
from Rails 7.1 will use the default Ruby implementation.
|
48
|
-
You can set `config.active_support.remove_deprecated_time_with_zone_name = true`
|
49
|
-
to enable the new behavior now.
|
50
|
-
EOM
|
51
|
-
|
52
|
-
"Time"
|
53
|
-
end
|
54
|
-
|
55
45
|
PRECISIONS = Hash.new { |h, n| h[n] = "%FT%T.%#{n}N" }
|
56
46
|
PRECISIONS[0] = "%FT%T"
|
57
47
|
|
@@ -78,7 +68,7 @@ module ActiveSupport
|
|
78
68
|
alias_method :getutc, :utc
|
79
69
|
alias_method :gmtime, :utc
|
80
70
|
|
81
|
-
# Returns the underlying
|
71
|
+
# Returns the underlying +TZInfo::TimezonePeriod+.
|
82
72
|
def period
|
83
73
|
@period ||= time_zone.period_for_utc(@utc)
|
84
74
|
end
|
@@ -95,7 +85,7 @@ module ActiveSupport
|
|
95
85
|
end
|
96
86
|
alias_method :getlocal, :localtime
|
97
87
|
|
98
|
-
# Returns true if the current time is within Daylight Savings Time for the
|
88
|
+
# Returns true if the current time is within Daylight Savings \Time for the
|
99
89
|
# specified time zone.
|
100
90
|
#
|
101
91
|
# Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
|
@@ -218,7 +208,7 @@ module ActiveSupport
|
|
218
208
|
# Accepts an optional <tt>format</tt>:
|
219
209
|
# * <tt>:default</tt> - default value, mimics Ruby Time#to_s format.
|
220
210
|
# * <tt>:db</tt> - format outputs time in UTC :db time. See Time#to_fs(:db).
|
221
|
-
# * Any key in
|
211
|
+
# * Any key in +Time::DATE_FORMATS+ can be used. See active_support/core_ext/time/conversions.rb.
|
222
212
|
def to_fs(format = :default)
|
223
213
|
if format == :db
|
224
214
|
utc.to_fs(format)
|
@@ -342,7 +332,7 @@ module ActiveSupport
|
|
342
332
|
#
|
343
333
|
def -(other)
|
344
334
|
if other.acts_like?(:time)
|
345
|
-
|
335
|
+
getutc - other.getutc
|
346
336
|
elsif duration_of_variable_length?(other)
|
347
337
|
method_missing(:-, other)
|
348
338
|
else
|
@@ -385,8 +375,8 @@ module ActiveSupport
|
|
385
375
|
#
|
386
376
|
# t = Time.zone.now # => Fri, 14 Apr 2017 11:45:15.116992711 EST -05:00
|
387
377
|
# t.change(year: 2020) # => Tue, 14 Apr 2020 11:45:15.116992711 EST -05:00
|
388
|
-
# t.change(hour: 12) # => Fri, 14 Apr 2017 12:00:00.
|
389
|
-
# t.change(min: 30) # => Fri, 14 Apr 2017 11:30:00.
|
378
|
+
# t.change(hour: 12) # => Fri, 14 Apr 2017 12:00:00.000000000 EST -05:00
|
379
|
+
# t.change(min: 30) # => Fri, 14 Apr 2017 11:30:00.000000000 EST -05:00
|
390
380
|
# t.change(offset: "-10:00") # => Fri, 14 Apr 2017 11:45:15.116992711 HST -10:00
|
391
381
|
# t.change(zone: "Hawaii") # => Fri, 14 Apr 2017 11:45:15.116992711 HST -10:00
|
392
382
|
def change(options)
|
@@ -516,6 +506,10 @@ module ActiveSupport
|
|
516
506
|
false
|
517
507
|
end
|
518
508
|
|
509
|
+
def present? # :nodoc:
|
510
|
+
true
|
511
|
+
end
|
512
|
+
|
519
513
|
def freeze
|
520
514
|
# preload instance variables before freezing
|
521
515
|
period; utc; time; to_datetime; to_time
|