activesupport 5.2.0 → 6.0.3.2

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.

Files changed (160) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +479 -330
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -3
  5. data/lib/active_support.rb +2 -1
  6. data/lib/active_support/actionable_error.rb +48 -0
  7. data/lib/active_support/backtrace_cleaner.rb +27 -1
  8. data/lib/active_support/cache.rb +104 -84
  9. data/lib/active_support/cache/file_store.rb +29 -30
  10. data/lib/active_support/cache/mem_cache_store.rb +14 -19
  11. data/lib/active_support/cache/memory_store.rb +15 -9
  12. data/lib/active_support/cache/null_store.rb +8 -3
  13. data/lib/active_support/cache/redis_cache_store.rb +73 -34
  14. data/lib/active_support/cache/strategy/local_cache.rb +23 -23
  15. data/lib/active_support/callbacks.rb +16 -8
  16. data/lib/active_support/concern.rb +31 -4
  17. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
  18. data/lib/active_support/concurrency/share_lock.rb +0 -1
  19. data/lib/active_support/configurable.rb +7 -11
  20. data/lib/active_support/core_ext/array.rb +1 -1
  21. data/lib/active_support/core_ext/array/access.rb +18 -6
  22. data/lib/active_support/core_ext/array/conversions.rb +5 -5
  23. data/lib/active_support/core_ext/array/extract.rb +21 -0
  24. data/lib/active_support/core_ext/array/prepend_and_append.rb +2 -6
  25. data/lib/active_support/core_ext/class/attribute.rb +11 -16
  26. data/lib/active_support/core_ext/class/subclasses.rb +1 -1
  27. data/lib/active_support/core_ext/date/calculations.rb +6 -5
  28. data/lib/active_support/core_ext/date_and_time/calculations.rb +24 -47
  29. data/lib/active_support/core_ext/date_and_time/zones.rb +0 -1
  30. data/lib/active_support/core_ext/date_time/calculations.rb +1 -1
  31. data/lib/active_support/core_ext/date_time/conversions.rb +0 -1
  32. data/lib/active_support/core_ext/digest.rb +3 -0
  33. data/lib/active_support/core_ext/enumerable.rb +97 -68
  34. data/lib/active_support/core_ext/file/atomic.rb +1 -1
  35. data/lib/active_support/core_ext/hash.rb +1 -2
  36. data/lib/active_support/core_ext/hash/compact.rb +2 -26
  37. data/lib/active_support/core_ext/hash/conversions.rb +1 -1
  38. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  39. data/lib/active_support/core_ext/hash/except.rb +1 -1
  40. data/lib/active_support/core_ext/hash/keys.rb +0 -29
  41. data/lib/active_support/core_ext/hash/slice.rb +3 -25
  42. data/lib/active_support/core_ext/hash/transform_values.rb +2 -29
  43. data/lib/active_support/core_ext/integer/multiple.rb +1 -1
  44. data/lib/active_support/core_ext/kernel.rb +0 -1
  45. data/lib/active_support/core_ext/load_error.rb +1 -1
  46. data/lib/active_support/core_ext/module.rb +0 -1
  47. data/lib/active_support/core_ext/module/attribute_accessors.rb +7 -10
  48. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +13 -19
  49. data/lib/active_support/core_ext/module/delegation.rb +41 -8
  50. data/lib/active_support/core_ext/module/introspection.rb +38 -13
  51. data/lib/active_support/core_ext/module/reachable.rb +1 -6
  52. data/lib/active_support/core_ext/module/redefine_method.rb +8 -17
  53. data/lib/active_support/core_ext/numeric.rb +0 -1
  54. data/lib/active_support/core_ext/numeric/conversions.rb +124 -128
  55. data/lib/active_support/core_ext/numeric/inquiry.rb +2 -25
  56. data/lib/active_support/core_ext/object/blank.rb +1 -2
  57. data/lib/active_support/core_ext/object/duplicable.rb +7 -114
  58. data/lib/active_support/core_ext/object/json.rb +1 -0
  59. data/lib/active_support/core_ext/object/to_query.rb +5 -2
  60. data/lib/active_support/core_ext/object/try.rb +17 -7
  61. data/lib/active_support/core_ext/object/with_options.rb +1 -1
  62. data/lib/active_support/core_ext/range.rb +1 -1
  63. data/lib/active_support/core_ext/range/compare_range.rb +76 -0
  64. data/lib/active_support/core_ext/range/conversions.rb +31 -29
  65. data/lib/active_support/core_ext/range/each.rb +0 -1
  66. data/lib/active_support/core_ext/range/include_range.rb +6 -22
  67. data/lib/active_support/core_ext/range/include_time_with_zone.rb +2 -2
  68. data/lib/active_support/core_ext/regexp.rb +0 -4
  69. data/lib/active_support/core_ext/securerandom.rb +23 -3
  70. data/lib/active_support/core_ext/string/access.rb +8 -0
  71. data/lib/active_support/core_ext/string/filters.rb +42 -1
  72. data/lib/active_support/core_ext/string/inflections.rb +7 -2
  73. data/lib/active_support/core_ext/string/multibyte.rb +4 -3
  74. data/lib/active_support/core_ext/string/output_safety.rb +63 -6
  75. data/lib/active_support/core_ext/string/strip.rb +3 -1
  76. data/lib/active_support/core_ext/time/calculations.rb +31 -2
  77. data/lib/active_support/core_ext/uri.rb +2 -4
  78. data/lib/active_support/current_attributes.rb +8 -0
  79. data/lib/active_support/dependencies.rb +77 -18
  80. data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
  81. data/lib/active_support/deprecation.rb +1 -1
  82. data/lib/active_support/deprecation/behaviors.rb +5 -1
  83. data/lib/active_support/deprecation/method_wrappers.rb +20 -13
  84. data/lib/active_support/deprecation/proxy_wrappers.rb +28 -5
  85. data/lib/active_support/deprecation/reporting.rb +1 -1
  86. data/lib/active_support/descendants_tracker.rb +55 -9
  87. data/lib/active_support/duration.rb +19 -16
  88. data/lib/active_support/duration/iso8601_parser.rb +2 -4
  89. data/lib/active_support/duration/iso8601_serializer.rb +3 -5
  90. data/lib/active_support/encrypted_configuration.rb +1 -5
  91. data/lib/active_support/encrypted_file.rb +4 -3
  92. data/lib/active_support/evented_file_update_checker.rb +39 -10
  93. data/lib/active_support/execution_wrapper.rb +1 -0
  94. data/lib/active_support/file_update_checker.rb +0 -1
  95. data/lib/active_support/gem_version.rb +4 -4
  96. data/lib/active_support/hash_with_indifferent_access.rb +36 -18
  97. data/lib/active_support/i18n.rb +1 -0
  98. data/lib/active_support/i18n_railtie.rb +18 -2
  99. data/lib/active_support/inflector/inflections.rb +1 -5
  100. data/lib/active_support/inflector/methods.rb +18 -29
  101. data/lib/active_support/inflector/transliterate.rb +47 -18
  102. data/lib/active_support/json/decoding.rb +23 -24
  103. data/lib/active_support/json/encoding.rb +6 -2
  104. data/lib/active_support/key_generator.rb +0 -32
  105. data/lib/active_support/lazy_load_hooks.rb +5 -2
  106. data/lib/active_support/locale/en.rb +33 -0
  107. data/lib/active_support/log_subscriber.rb +31 -9
  108. data/lib/active_support/logger.rb +1 -16
  109. data/lib/active_support/logger_silence.rb +28 -12
  110. data/lib/active_support/logger_thread_safe_level.rb +28 -5
  111. data/lib/active_support/message_encryptor.rb +4 -6
  112. data/lib/active_support/message_verifier.rb +5 -5
  113. data/lib/active_support/messages/metadata.rb +3 -2
  114. data/lib/active_support/messages/rotator.rb +4 -4
  115. data/lib/active_support/multibyte/chars.rb +29 -49
  116. data/lib/active_support/multibyte/unicode.rb +44 -282
  117. data/lib/active_support/notifications.rb +41 -4
  118. data/lib/active_support/notifications/fanout.rb +100 -15
  119. data/lib/active_support/notifications/instrumenter.rb +80 -9
  120. data/lib/active_support/number_helper.rb +11 -0
  121. data/lib/active_support/number_helper/number_converter.rb +4 -5
  122. data/lib/active_support/number_helper/number_to_currency_converter.rb +9 -10
  123. data/lib/active_support/number_helper/number_to_delimited_converter.rb +3 -2
  124. data/lib/active_support/number_helper/number_to_human_converter.rb +3 -2
  125. data/lib/active_support/number_helper/number_to_human_size_converter.rb +3 -2
  126. data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
  127. data/lib/active_support/number_helper/number_to_phone_converter.rb +2 -1
  128. data/lib/active_support/number_helper/number_to_rounded_converter.rb +5 -4
  129. data/lib/active_support/option_merger.rb +21 -3
  130. data/lib/active_support/ordered_hash.rb +1 -1
  131. data/lib/active_support/ordered_options.rb +5 -1
  132. data/lib/active_support/parameter_filter.rb +128 -0
  133. data/lib/active_support/rails.rb +0 -6
  134. data/lib/active_support/reloader.rb +4 -5
  135. data/lib/active_support/security_utils.rb +1 -1
  136. data/lib/active_support/string_inquirer.rb +0 -1
  137. data/lib/active_support/subscriber.rb +65 -22
  138. data/lib/active_support/tagged_logging.rb +13 -4
  139. data/lib/active_support/test_case.rb +92 -1
  140. data/lib/active_support/testing/assertions.rb +15 -1
  141. data/lib/active_support/testing/deprecation.rb +0 -1
  142. data/lib/active_support/testing/file_fixtures.rb +2 -0
  143. data/lib/active_support/testing/isolation.rb +2 -2
  144. data/lib/active_support/testing/method_call_assertions.rb +28 -1
  145. data/lib/active_support/testing/parallelization.rb +134 -0
  146. data/lib/active_support/testing/setup_and_teardown.rb +5 -9
  147. data/lib/active_support/testing/stream.rb +1 -2
  148. data/lib/active_support/testing/time_helpers.rb +7 -9
  149. data/lib/active_support/time_with_zone.rb +15 -5
  150. data/lib/active_support/values/time_zone.rb +14 -8
  151. data/lib/active_support/xml_mini.rb +2 -10
  152. data/lib/active_support/xml_mini/jdom.rb +2 -3
  153. data/lib/active_support/xml_mini/libxml.rb +2 -2
  154. data/lib/active_support/xml_mini/libxmlsax.rb +4 -4
  155. data/lib/active_support/xml_mini/nokogiri.rb +2 -2
  156. data/lib/active_support/xml_mini/nokogirisax.rb +3 -3
  157. data/lib/active_support/xml_mini/rexml.rb +2 -2
  158. metadata +42 -13
  159. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -13
  160. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -46,21 +46,30 @@ module ActiveSupport
46
46
 
47
47
  def current_tags
48
48
  # We use our object ID here to avoid conflicting with other instances
49
- thread_key = @thread_key ||= "activesupport_tagged_logging_tags:#{object_id}".freeze
49
+ thread_key = @thread_key ||= "activesupport_tagged_logging_tags:#{object_id}"
50
50
  Thread.current[thread_key] ||= []
51
51
  end
52
52
 
53
53
  def tags_text
54
54
  tags = current_tags
55
- if tags.any?
55
+ if tags.one?
56
+ "[#{tags[0]}] "
57
+ elsif tags.any?
56
58
  tags.collect { |tag| "[#{tag}] " }.join
57
59
  end
58
60
  end
59
61
  end
60
62
 
61
63
  def self.new(logger)
62
- # Ensure we set a default formatter so we aren't extending nil!
63
- logger.formatter ||= ActiveSupport::Logger::SimpleFormatter.new
64
+ logger = logger.dup
65
+
66
+ if logger.formatter
67
+ logger.formatter = logger.formatter.dup
68
+ else
69
+ # Ensure we set a default formatter so we aren't extending nil!
70
+ logger.formatter = ActiveSupport::Logger::SimpleFormatter.new
71
+ end
72
+
64
73
  logger.formatter.extend Formatter
65
74
  logger.extend(self)
66
75
  end
@@ -11,6 +11,8 @@ require "active_support/testing/isolation"
11
11
  require "active_support/testing/constant_lookup"
12
12
  require "active_support/testing/time_helpers"
13
13
  require "active_support/testing/file_fixtures"
14
+ require "active_support/testing/parallelization"
15
+ require "concurrent/utility/processor_counter"
14
16
 
15
17
  module ActiveSupport
16
18
  class TestCase < ::Minitest::Test
@@ -39,12 +41,101 @@ module ActiveSupport
39
41
  def test_order
40
42
  ActiveSupport.test_order ||= :random
41
43
  end
44
+
45
+ # Parallelizes the test suite.
46
+ #
47
+ # Takes a +workers+ argument that controls how many times the process
48
+ # is forked. For each process a new database will be created suffixed
49
+ # with the worker number.
50
+ #
51
+ # test-database-0
52
+ # test-database-1
53
+ #
54
+ # If <tt>ENV["PARALLEL_WORKERS"]</tt> is set the workers argument will be ignored
55
+ # and the environment variable will be used instead. This is useful for CI
56
+ # environments, or other environments where you may need more workers than
57
+ # you do for local testing.
58
+ #
59
+ # If the number of workers is set to +1+ or fewer, the tests will not be
60
+ # parallelized.
61
+ #
62
+ # If +workers+ is set to +:number_of_processors+, the number of workers will be
63
+ # set to the actual core count on the machine you are on.
64
+ #
65
+ # The default parallelization method is to fork processes. If you'd like to
66
+ # use threads instead you can pass <tt>with: :threads</tt> to the +parallelize+
67
+ # method. Note the threaded parallelization does not create multiple
68
+ # database and will not work with system tests at this time.
69
+ #
70
+ # parallelize(workers: :number_of_processors, with: :threads)
71
+ #
72
+ # The threaded parallelization uses minitest's parallel executor directly.
73
+ # The processes parallelization uses a Ruby DRb server.
74
+ def parallelize(workers: :number_of_processors, with: :processes)
75
+ workers = Concurrent.physical_processor_count if workers == :number_of_processors
76
+ workers = ENV["PARALLEL_WORKERS"].to_i if ENV["PARALLEL_WORKERS"]
77
+
78
+ return if workers <= 1
79
+
80
+ executor = case with
81
+ when :processes
82
+ Testing::Parallelization.new(workers)
83
+ when :threads
84
+ Minitest::Parallel::Executor.new(workers)
85
+ else
86
+ raise ArgumentError, "#{with} is not a supported parallelization executor."
87
+ end
88
+
89
+ self.lock_threads = false if defined?(self.lock_threads) && with == :threads
90
+
91
+ Minitest.parallel_executor = executor
92
+
93
+ parallelize_me!
94
+ end
95
+
96
+ # Set up hook for parallel testing. This can be used if you have multiple
97
+ # databases or any behavior that needs to be run after the process is forked
98
+ # but before the tests run.
99
+ #
100
+ # Note: this feature is not available with the threaded parallelization.
101
+ #
102
+ # In your +test_helper.rb+ add the following:
103
+ #
104
+ # class ActiveSupport::TestCase
105
+ # parallelize_setup do
106
+ # # create databases
107
+ # end
108
+ # end
109
+ def parallelize_setup(&block)
110
+ ActiveSupport::Testing::Parallelization.after_fork_hook do |worker|
111
+ yield worker
112
+ end
113
+ end
114
+
115
+ # Clean up hook for parallel testing. This can be used to drop databases
116
+ # if your app uses multiple write/read databases or other clean up before
117
+ # the tests finish. This runs before the forked process is closed.
118
+ #
119
+ # Note: this feature is not available with the threaded parallelization.
120
+ #
121
+ # In your +test_helper.rb+ add the following:
122
+ #
123
+ # class ActiveSupport::TestCase
124
+ # parallelize_teardown do
125
+ # # drop databases
126
+ # end
127
+ # end
128
+ def parallelize_teardown(&block)
129
+ ActiveSupport::Testing::Parallelization.run_cleanup_hook do |worker|
130
+ yield worker
131
+ end
132
+ end
42
133
  end
43
134
 
44
135
  alias_method :method_name, :name
45
136
 
46
137
  include ActiveSupport::Testing::TaggedLogging
47
- include ActiveSupport::Testing::SetupAndTeardown
138
+ prepend ActiveSupport::Testing::SetupAndTeardown
48
139
  include ActiveSupport::Testing::Assertions
49
140
  include ActiveSupport::Testing::Deprecation
50
141
  include ActiveSupport::Testing::TimeHelpers
@@ -113,11 +113,23 @@ module ActiveSupport
113
113
  # post :create, params: { article: invalid_attributes }
114
114
  # end
115
115
  #
116
+ # A lambda can be passed in and evaluated.
117
+ #
118
+ # assert_no_difference -> { Article.count } do
119
+ # post :create, params: { article: invalid_attributes }
120
+ # end
121
+ #
116
122
  # An error message can be specified.
117
123
  #
118
124
  # assert_no_difference 'Article.count', 'An Article should not be created' do
119
125
  # post :create, params: { article: invalid_attributes }
120
126
  # end
127
+ #
128
+ # An array of expressions can also be passed in and evaluated.
129
+ #
130
+ # assert_no_difference [ 'Article.count', -> { Post.count } ] do
131
+ # post :create, params: { article: invalid_attributes }
132
+ # end
121
133
  def assert_no_difference(expression, message = nil, &block)
122
134
  assert_difference expression, 0, message, &block
123
135
  end
@@ -176,7 +188,9 @@ module ActiveSupport
176
188
  assert before != after, error
177
189
 
178
190
  unless to == UNTRACKED
179
- error = "#{expression.inspect} didn't change to #{to}"
191
+ error = "#{expression.inspect} didn't change to as expected\n"
192
+ error = "#{error}Expected: #{to.inspect}\n"
193
+ error = "#{error} Actual: #{after.inspect}"
180
194
  error = "#{message}.\n#{error}" if message
181
195
  assert to === after, error
182
196
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_support/deprecation"
4
- require "active_support/core_ext/regexp"
5
4
 
6
5
  module ActiveSupport
7
6
  module Testing
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_support/concern"
4
+
3
5
  module ActiveSupport
4
6
  module Testing
5
7
  # Adds simple access to sample files called file fixtures.
@@ -56,7 +56,7 @@ module ActiveSupport
56
56
  write.close
57
57
  result = read.read
58
58
  Process.wait2(pid)
59
- result.unpack("m")[0]
59
+ result.unpack1("m")
60
60
  end
61
61
  end
62
62
 
@@ -98,7 +98,7 @@ module ActiveSupport
98
98
  nil
99
99
  end
100
100
 
101
- return tmpfile.read.unpack("m")[0]
101
+ return tmpfile.read.unpack1("m")
102
102
  end
103
103
  end
104
104
  end
@@ -17,7 +17,7 @@ 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: nil)
20
+ def assert_called_with(object, method_name, args, returns: nil)
21
21
  mock = Minitest::Mock.new
22
22
 
23
23
  if args.all? { |arg| arg.is_a?(Array) }
@@ -35,6 +35,33 @@ module ActiveSupport
35
35
  assert_called(object, method_name, message, times: 0, &block)
36
36
  end
37
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
+
38
65
  def stub_any_instance(klass, instance: klass.new)
39
66
  klass.stub(:new, instance) { yield instance }
40
67
  end
@@ -0,0 +1,134 @@
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
+
7
+ module ActiveSupport
8
+ module Testing
9
+ class Parallelization # :nodoc:
10
+ class Server
11
+ include DRb::DRbUndumped
12
+
13
+ def initialize
14
+ @queue = Queue.new
15
+ end
16
+
17
+ def record(reporter, result)
18
+ raise DRb::DRbConnError if result.is_a?(DRb::DRbUnknown)
19
+
20
+ reporter.synchronize do
21
+ reporter.record(result)
22
+ end
23
+ end
24
+
25
+ def <<(o)
26
+ o[2] = DRbObject.new(o[2]) if o
27
+ @queue << o
28
+ end
29
+
30
+ def length
31
+ @queue.length
32
+ end
33
+
34
+ def pop; @queue.pop; end
35
+ end
36
+
37
+ @@after_fork_hooks = []
38
+
39
+ def self.after_fork_hook(&blk)
40
+ @@after_fork_hooks << blk
41
+ end
42
+
43
+ cattr_reader :after_fork_hooks
44
+
45
+ @@run_cleanup_hooks = []
46
+
47
+ def self.run_cleanup_hook(&blk)
48
+ @@run_cleanup_hooks << blk
49
+ end
50
+
51
+ cattr_reader :run_cleanup_hooks
52
+
53
+ def initialize(queue_size)
54
+ @queue_size = queue_size
55
+ @queue = Server.new
56
+ @pool = []
57
+
58
+ @url = DRb.start_service("drbunix:", @queue).uri
59
+ end
60
+
61
+ def after_fork(worker)
62
+ self.class.after_fork_hooks.each do |cb|
63
+ cb.call(worker)
64
+ end
65
+ end
66
+
67
+ def run_cleanup(worker)
68
+ self.class.run_cleanup_hooks.each do |cb|
69
+ cb.call(worker)
70
+ end
71
+ end
72
+
73
+ def start
74
+ @pool = @queue_size.times.map do |worker|
75
+ fork do
76
+ DRb.stop_service
77
+
78
+ begin
79
+ after_fork(worker)
80
+ rescue => setup_exception; end
81
+
82
+ queue = DRbObject.new_with_uri(@url)
83
+
84
+ while job = queue.pop
85
+ klass = job[0]
86
+ method = job[1]
87
+ reporter = job[2]
88
+ result = klass.with_info_handler reporter do
89
+ Minitest.run_one_method(klass, method)
90
+ end
91
+
92
+ add_setup_exception(result, setup_exception) if setup_exception
93
+
94
+ begin
95
+ queue.record(reporter, result)
96
+ rescue DRb::DRbConnError
97
+ result.failures.map! do |failure|
98
+ if failure.respond_to?(:error)
99
+ # minitest >5.14.0
100
+ error = DRb::DRbRemoteError.new(failure.error)
101
+ else
102
+ error = DRb::DRbRemoteError.new(failure.exception)
103
+ end
104
+ Minitest::UnexpectedError.new(error)
105
+ end
106
+ queue.record(reporter, result)
107
+ end
108
+ end
109
+ ensure
110
+ run_cleanup(worker)
111
+ end
112
+ end
113
+ end
114
+
115
+ def <<(work)
116
+ @queue << work
117
+ end
118
+
119
+ def shutdown
120
+ @queue_size.times { @queue << nil }
121
+ @pool.each { |pid| Process.waitpid pid }
122
+
123
+ if @queue.length > 0
124
+ raise "Queue not empty, but all workers have finished. This probably means that a worker crashed and #{@queue.length} tests were missed."
125
+ end
126
+ end
127
+
128
+ private
129
+ def add_setup_exception(result, setup_exception)
130
+ result.failures.prepend Minitest::UnexpectedError.new(setup_exception)
131
+ end
132
+ end
133
+ end
134
+ end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/concern"
4
3
  require "active_support/callbacks"
5
4
 
6
5
  module ActiveSupport
@@ -19,11 +18,10 @@ module ActiveSupport
19
18
  # end
20
19
  # end
21
20
  module SetupAndTeardown
22
- extend ActiveSupport::Concern
23
-
24
- included do
25
- include ActiveSupport::Callbacks
26
- define_callbacks :setup, :teardown
21
+ def self.prepended(klass)
22
+ klass.include ActiveSupport::Callbacks
23
+ klass.define_callbacks :setup, :teardown
24
+ klass.extend ClassMethods
27
25
  end
28
26
 
29
27
  module ClassMethods
@@ -47,12 +45,10 @@ module ActiveSupport
47
45
  begin
48
46
  run_callbacks :teardown
49
47
  rescue => e
50
- error = e
48
+ self.failures << Minitest::UnexpectedError.new(e)
51
49
  end
52
50
 
53
51
  super
54
- ensure
55
- raise error if error
56
52
  end
57
53
  end
58
54
  end
@@ -4,7 +4,6 @@ module ActiveSupport
4
4
  module Testing
5
5
  module Stream #:nodoc:
6
6
  private
7
-
8
7
  def silence_stream(stream)
9
8
  old_stream = stream.dup
10
9
  stream.reopen(IO::NULL)
@@ -33,7 +32,7 @@ module ActiveSupport
33
32
  yield
34
33
 
35
34
  stream_io.rewind
36
- return captured_stream.read
35
+ captured_stream.read
37
36
  ensure
38
37
  captured_stream.close
39
38
  captured_stream.unlink