activesupport 4.2.11.1 → 6.0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of activesupport might be problematic. Click here for more details.

Files changed (263) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +399 -411
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +7 -7
  5. data/lib/active_support/actionable_error.rb +48 -0
  6. data/lib/active_support/all.rb +5 -3
  7. data/lib/active_support/array_inquirer.rb +48 -0
  8. data/lib/active_support/backtrace_cleaner.rb +34 -6
  9. data/lib/active_support/benchmarkable.rb +6 -4
  10. data/lib/active_support/builder.rb +3 -1
  11. data/lib/active_support/cache/file_store.rb +58 -53
  12. data/lib/active_support/cache/mem_cache_store.rb +95 -91
  13. data/lib/active_support/cache/memory_store.rb +39 -36
  14. data/lib/active_support/cache/null_store.rb +11 -7
  15. data/lib/active_support/cache/redis_cache_store.rb +493 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +75 -42
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
  18. data/lib/active_support/cache.rb +331 -217
  19. data/lib/active_support/callbacks.rb +650 -592
  20. data/lib/active_support/concern.rb +35 -6
  21. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +35 -0
  22. data/lib/active_support/concurrency/share_lock.rb +226 -0
  23. data/lib/active_support/configurable.rb +13 -14
  24. data/lib/active_support/core_ext/array/access.rb +41 -1
  25. data/lib/active_support/core_ext/array/conversions.rb +24 -20
  26. data/lib/active_support/core_ext/array/extract.rb +21 -0
  27. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  28. data/lib/active_support/core_ext/array/grouping.rb +11 -18
  29. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  30. data/lib/active_support/core_ext/array/prepend_and_append.rb +4 -6
  31. data/lib/active_support/core_ext/array/wrap.rb +7 -4
  32. data/lib/active_support/core_ext/array.rb +9 -6
  33. data/lib/active_support/core_ext/benchmark.rb +3 -1
  34. data/lib/active_support/core_ext/big_decimal/conversions.rb +10 -12
  35. data/lib/active_support/core_ext/big_decimal.rb +3 -1
  36. data/lib/active_support/core_ext/class/attribute.rb +45 -31
  37. data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
  38. data/lib/active_support/core_ext/class/subclasses.rb +20 -6
  39. data/lib/active_support/core_ext/class.rb +4 -3
  40. data/lib/active_support/core_ext/date/acts_like.rb +3 -1
  41. data/lib/active_support/core_ext/date/blank.rb +14 -0
  42. data/lib/active_support/core_ext/date/calculations.rb +17 -14
  43. data/lib/active_support/core_ext/date/conversions.rb +25 -23
  44. data/lib/active_support/core_ext/date/zones.rb +4 -2
  45. data/lib/active_support/core_ext/date.rb +6 -4
  46. data/lib/active_support/core_ext/date_and_time/calculations.rb +154 -65
  47. data/lib/active_support/core_ext/date_and_time/compatibility.rb +4 -3
  48. data/lib/active_support/core_ext/date_and_time/zones.rb +12 -13
  49. data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
  50. data/lib/active_support/core_ext/date_time/blank.rb +14 -0
  51. data/lib/active_support/core_ext/date_time/calculations.rb +37 -19
  52. data/lib/active_support/core_ext/date_time/compatibility.rb +8 -6
  53. data/lib/active_support/core_ext/date_time/conversions.rb +16 -13
  54. data/lib/active_support/core_ext/date_time.rb +7 -5
  55. data/lib/active_support/core_ext/digest/uuid.rb +7 -5
  56. data/lib/active_support/core_ext/digest.rb +3 -0
  57. data/lib/active_support/core_ext/enumerable.rb +114 -22
  58. data/lib/active_support/core_ext/file/atomic.rb +38 -31
  59. data/lib/active_support/core_ext/file.rb +3 -1
  60. data/lib/active_support/core_ext/hash/compact.rb +4 -23
  61. data/lib/active_support/core_ext/hash/conversions.rb +62 -41
  62. data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
  63. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  64. data/lib/active_support/core_ext/hash/except.rb +12 -9
  65. data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
  66. data/lib/active_support/core_ext/hash/keys.rb +19 -42
  67. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  68. data/lib/active_support/core_ext/hash/slice.rb +5 -27
  69. data/lib/active_support/core_ext/hash/transform_values.rb +4 -22
  70. data/lib/active_support/core_ext/hash.rb +10 -9
  71. data/lib/active_support/core_ext/integer/inflections.rb +3 -1
  72. data/lib/active_support/core_ext/integer/multiple.rb +3 -1
  73. data/lib/active_support/core_ext/integer/time.rb +11 -18
  74. data/lib/active_support/core_ext/integer.rb +5 -3
  75. data/lib/active_support/core_ext/kernel/concern.rb +5 -1
  76. data/lib/active_support/core_ext/kernel/reporting.rb +4 -84
  77. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  78. data/lib/active_support/core_ext/kernel.rb +5 -5
  79. data/lib/active_support/core_ext/load_error.rb +3 -22
  80. data/lib/active_support/core_ext/marshal.rb +8 -8
  81. data/lib/active_support/core_ext/module/aliasing.rb +6 -44
  82. data/lib/active_support/core_ext/module/anonymous.rb +12 -1
  83. data/lib/active_support/core_ext/module/attr_internal.rb +8 -9
  84. data/lib/active_support/core_ext/module/attribute_accessors.rb +46 -46
  85. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +144 -0
  86. data/lib/active_support/core_ext/module/concerning.rb +11 -12
  87. data/lib/active_support/core_ext/module/delegation.rb +133 -30
  88. data/lib/active_support/core_ext/module/deprecation.rb +4 -2
  89. data/lib/active_support/core_ext/module/introspection.rb +44 -19
  90. data/lib/active_support/core_ext/module/reachable.rb +5 -7
  91. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  92. data/lib/active_support/core_ext/module/remove_method.rb +8 -3
  93. data/lib/active_support/core_ext/module.rb +13 -11
  94. data/lib/active_support/core_ext/name_error.rb +22 -2
  95. data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
  96. data/lib/active_support/core_ext/numeric/conversions.rb +129 -136
  97. data/lib/active_support/core_ext/numeric/inquiry.rb +5 -0
  98. data/lib/active_support/core_ext/numeric/time.rb +35 -23
  99. data/lib/active_support/core_ext/numeric.rb +5 -3
  100. data/lib/active_support/core_ext/object/acts_like.rb +12 -1
  101. data/lib/active_support/core_ext/object/blank.rb +27 -3
  102. data/lib/active_support/core_ext/object/conversions.rb +6 -4
  103. data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
  104. data/lib/active_support/core_ext/object/duplicable.rb +13 -93
  105. data/lib/active_support/core_ext/object/inclusion.rb +5 -3
  106. data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
  107. data/lib/active_support/core_ext/object/json.rb +51 -20
  108. data/lib/active_support/core_ext/object/to_param.rb +3 -1
  109. data/lib/active_support/core_ext/object/to_query.rb +10 -5
  110. data/lib/active_support/core_ext/object/try.rb +81 -23
  111. data/lib/active_support/core_ext/object/with_options.rb +16 -3
  112. data/lib/active_support/core_ext/object.rb +14 -13
  113. data/lib/active_support/core_ext/range/compare_range.rb +76 -0
  114. data/lib/active_support/core_ext/range/conversions.rb +37 -15
  115. data/lib/active_support/core_ext/range/each.rb +18 -17
  116. data/lib/active_support/core_ext/range/include_range.rb +7 -21
  117. data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
  118. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  119. data/lib/active_support/core_ext/range.rb +7 -4
  120. data/lib/active_support/core_ext/regexp.rb +2 -0
  121. data/lib/active_support/core_ext/securerandom.rb +45 -0
  122. data/lib/active_support/core_ext/string/access.rb +16 -6
  123. data/lib/active_support/core_ext/string/behavior.rb +3 -1
  124. data/lib/active_support/core_ext/string/conversions.rb +7 -4
  125. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  126. data/lib/active_support/core_ext/string/filters.rb +48 -6
  127. data/lib/active_support/core_ext/string/indent.rb +6 -4
  128. data/lib/active_support/core_ext/string/inflections.rb +66 -24
  129. data/lib/active_support/core_ext/string/inquiry.rb +3 -1
  130. data/lib/active_support/core_ext/string/multibyte.rb +16 -7
  131. data/lib/active_support/core_ext/string/output_safety.rb +93 -40
  132. data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
  133. data/lib/active_support/core_ext/string/strip.rb +6 -5
  134. data/lib/active_support/core_ext/string/zones.rb +4 -2
  135. data/lib/active_support/core_ext/string.rb +15 -13
  136. data/lib/active_support/core_ext/time/acts_like.rb +3 -1
  137. data/lib/active_support/core_ext/time/calculations.rb +115 -52
  138. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  139. data/lib/active_support/core_ext/time/conversions.rb +20 -13
  140. data/lib/active_support/core_ext/time/zones.rb +41 -7
  141. data/lib/active_support/core_ext/time.rb +7 -6
  142. data/lib/active_support/core_ext/uri.rb +6 -7
  143. data/lib/active_support/core_ext.rb +3 -1
  144. data/lib/active_support/current_attributes.rb +203 -0
  145. data/lib/active_support/dependencies/autoload.rb +2 -0
  146. data/lib/active_support/dependencies/interlock.rb +57 -0
  147. data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
  148. data/lib/active_support/dependencies.rb +208 -166
  149. data/lib/active_support/deprecation/behaviors.rb +44 -11
  150. data/lib/active_support/deprecation/constant_accessor.rb +52 -0
  151. data/lib/active_support/deprecation/instance_delegator.rb +17 -2
  152. data/lib/active_support/deprecation/method_wrappers.rb +61 -21
  153. data/lib/active_support/deprecation/proxy_wrappers.rb +81 -30
  154. data/lib/active_support/deprecation/reporting.rb +32 -12
  155. data/lib/active_support/deprecation.rb +12 -9
  156. data/lib/active_support/descendants_tracker.rb +57 -9
  157. data/lib/active_support/digest.rb +20 -0
  158. data/lib/active_support/duration/iso8601_parser.rb +123 -0
  159. data/lib/active_support/duration/iso8601_serializer.rb +53 -0
  160. data/lib/active_support/duration.rb +315 -40
  161. data/lib/active_support/encrypted_configuration.rb +45 -0
  162. data/lib/active_support/encrypted_file.rb +100 -0
  163. data/lib/active_support/evented_file_update_checker.rb +234 -0
  164. data/lib/active_support/execution_wrapper.rb +129 -0
  165. data/lib/active_support/executor.rb +8 -0
  166. data/lib/active_support/file_update_checker.rb +62 -37
  167. data/lib/active_support/gem_version.rb +6 -4
  168. data/lib/active_support/gzip.rb +7 -5
  169. data/lib/active_support/hash_with_indifferent_access.rb +129 -30
  170. data/lib/active_support/i18n.rb +9 -6
  171. data/lib/active_support/i18n_railtie.rb +50 -14
  172. data/lib/active_support/inflections.rb +13 -11
  173. data/lib/active_support/inflector/inflections.rb +58 -13
  174. data/lib/active_support/inflector/methods.rb +159 -145
  175. data/lib/active_support/inflector/transliterate.rb +84 -34
  176. data/lib/active_support/inflector.rb +7 -5
  177. data/lib/active_support/json/decoding.rb +32 -30
  178. data/lib/active_support/json/encoding.rb +17 -60
  179. data/lib/active_support/json.rb +4 -2
  180. data/lib/active_support/key_generator.rb +11 -43
  181. data/lib/active_support/lazy_load_hooks.rb +53 -20
  182. data/lib/active_support/locale/en.rb +33 -0
  183. data/lib/active_support/locale/en.yml +2 -0
  184. data/lib/active_support/log_subscriber/test_helper.rb +14 -12
  185. data/lib/active_support/log_subscriber.rb +44 -19
  186. data/lib/active_support/logger.rb +9 -23
  187. data/lib/active_support/logger_silence.rb +32 -14
  188. data/lib/active_support/logger_thread_safe_level.rb +32 -8
  189. data/lib/active_support/message_encryptor.rb +166 -53
  190. data/lib/active_support/message_verifier.rb +149 -16
  191. data/lib/active_support/messages/metadata.rb +72 -0
  192. data/lib/active_support/messages/rotation_configuration.rb +22 -0
  193. data/lib/active_support/messages/rotator.rb +56 -0
  194. data/lib/active_support/multibyte/chars.rb +56 -63
  195. data/lib/active_support/multibyte/unicode.rb +56 -290
  196. data/lib/active_support/multibyte.rb +4 -2
  197. data/lib/active_support/notifications/fanout.rb +109 -22
  198. data/lib/active_support/notifications/instrumenter.rb +107 -16
  199. data/lib/active_support/notifications.rb +51 -10
  200. data/lib/active_support/number_helper/number_converter.rb +16 -15
  201. data/lib/active_support/number_helper/number_to_currency_converter.rb +14 -15
  202. data/lib/active_support/number_helper/number_to_delimited_converter.rb +11 -4
  203. data/lib/active_support/number_helper/number_to_human_converter.rb +13 -10
  204. data/lib/active_support/number_helper/number_to_human_size_converter.rb +11 -9
  205. data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
  206. data/lib/active_support/number_helper/number_to_phone_converter.rb +15 -5
  207. data/lib/active_support/number_helper/number_to_rounded_converter.rb +25 -57
  208. data/lib/active_support/number_helper/rounding_helper.rb +66 -0
  209. data/lib/active_support/number_helper.rb +105 -68
  210. data/lib/active_support/option_merger.rb +24 -4
  211. data/lib/active_support/ordered_hash.rb +7 -5
  212. data/lib/active_support/ordered_options.rb +27 -5
  213. data/lib/active_support/parameter_filter.rb +128 -0
  214. data/lib/active_support/per_thread_registry.rb +9 -4
  215. data/lib/active_support/proxy_object.rb +2 -0
  216. data/lib/active_support/rails.rb +10 -8
  217. data/lib/active_support/railtie.rb +43 -9
  218. data/lib/active_support/reloader.rb +130 -0
  219. data/lib/active_support/rescuable.rb +108 -53
  220. data/lib/active_support/security_utils.rb +15 -11
  221. data/lib/active_support/string_inquirer.rb +11 -4
  222. data/lib/active_support/subscriber.rb +74 -30
  223. data/lib/active_support/tagged_logging.rb +25 -13
  224. data/lib/active_support/test_case.rb +107 -44
  225. data/lib/active_support/testing/assertions.rb +151 -20
  226. data/lib/active_support/testing/autorun.rb +4 -2
  227. data/lib/active_support/testing/constant_lookup.rb +2 -1
  228. data/lib/active_support/testing/declarative.rb +3 -1
  229. data/lib/active_support/testing/deprecation.rb +13 -10
  230. data/lib/active_support/testing/file_fixtures.rb +38 -0
  231. data/lib/active_support/testing/isolation.rb +35 -26
  232. data/lib/active_support/testing/method_call_assertions.rb +70 -0
  233. data/lib/active_support/testing/parallelization.rb +134 -0
  234. data/lib/active_support/testing/setup_and_teardown.rb +13 -8
  235. data/lib/active_support/testing/stream.rb +43 -0
  236. data/lib/active_support/testing/tagged_logging.rb +3 -1
  237. data/lib/active_support/testing/time_helpers.rb +84 -20
  238. data/lib/active_support/time.rb +14 -12
  239. data/lib/active_support/time_with_zone.rb +179 -39
  240. data/lib/active_support/values/time_zone.rb +203 -63
  241. data/lib/active_support/version.rb +3 -1
  242. data/lib/active_support/xml_mini/jdom.rb +116 -115
  243. data/lib/active_support/xml_mini/libxml.rb +16 -13
  244. data/lib/active_support/xml_mini/libxmlsax.rb +15 -14
  245. data/lib/active_support/xml_mini/nokogiri.rb +14 -12
  246. data/lib/active_support/xml_mini/nokogirisax.rb +14 -13
  247. data/lib/active_support/xml_mini/rexml.rb +11 -9
  248. data/lib/active_support/xml_mini.rb +38 -46
  249. data/lib/active_support.rb +13 -11
  250. metadata +84 -26
  251. data/lib/active_support/concurrency/latch.rb +0 -27
  252. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
  253. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
  254. data/lib/active_support/core_ext/date_time/zones.rb +0 -6
  255. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  256. data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
  257. data/lib/active_support/core_ext/module/method_transplanting.rb +0 -13
  258. data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
  259. data/lib/active_support/core_ext/object/itself.rb +0 -15
  260. data/lib/active_support/core_ext/struct.rb +0 -6
  261. data/lib/active_support/core_ext/thread.rb +0 -86
  262. data/lib/active_support/core_ext/time/marshal.rb +0 -30
  263. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,5 +1,7 @@
1
- gem 'minitest'
1
+ # frozen_string_literal: true
2
2
 
3
- require 'minitest'
3
+ gem "minitest"
4
+
5
+ require "minitest"
4
6
 
5
7
  Minitest.autorun
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/concern"
2
4
  require "active_support/inflector"
3
5
 
@@ -44,7 +46,6 @@ module ActiveSupport
44
46
  end
45
47
  end
46
48
  end
47
-
48
49
  end
49
50
  end
50
51
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  module Testing
3
5
  module Declarative
@@ -9,7 +11,7 @@ module ActiveSupport
9
11
  # ...
10
12
  # end
11
13
  def test(name, &block)
12
- test_name = "test_#{name.gsub(/\s+/,'_')}".to_sym
14
+ test_name = "test_#{name.gsub(/\s+/, '_')}".to_sym
13
15
  defined = method_defined? test_name
14
16
  raise "#{test_name} is already defined in #{self}" if defined
15
17
  if block_given?
@@ -1,34 +1,37 @@
1
- require 'active_support/deprecation'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/deprecation"
2
4
 
3
5
  module ActiveSupport
4
6
  module Testing
5
7
  module Deprecation #:nodoc:
6
- def assert_deprecated(match = nil, &block)
7
- result, warnings = collect_deprecations(&block)
8
+ def assert_deprecated(match = nil, deprecator = nil, &block)
9
+ result, warnings = collect_deprecations(deprecator, &block)
8
10
  assert !warnings.empty?, "Expected a deprecation warning within the block but received none"
9
11
  if match
10
12
  match = Regexp.new(Regexp.escape(match)) unless match.is_a?(Regexp)
11
- assert warnings.any? { |w| w =~ match }, "No deprecation warning matched #{match}: #{warnings.join(', ')}"
13
+ assert warnings.any? { |w| match.match?(w) }, "No deprecation warning matched #{match}: #{warnings.join(', ')}"
12
14
  end
13
15
  result
14
16
  end
15
17
 
16
- def assert_not_deprecated(&block)
17
- result, deprecations = collect_deprecations(&block)
18
+ def assert_not_deprecated(deprecator = nil, &block)
19
+ result, deprecations = collect_deprecations(deprecator, &block)
18
20
  assert deprecations.empty?, "Expected no deprecation warning within the block but received #{deprecations.size}: \n #{deprecations * "\n "}"
19
21
  result
20
22
  end
21
23
 
22
- def collect_deprecations
23
- old_behavior = ActiveSupport::Deprecation.behavior
24
+ def collect_deprecations(deprecator = nil)
25
+ deprecator ||= ActiveSupport::Deprecation
26
+ old_behavior = deprecator.behavior
24
27
  deprecations = []
25
- ActiveSupport::Deprecation.behavior = Proc.new do |message, callstack|
28
+ deprecator.behavior = Proc.new do |message, callstack|
26
29
  deprecations << message
27
30
  end
28
31
  result = yield
29
32
  [result, deprecations]
30
33
  ensure
31
- ActiveSupport::Deprecation.behavior = old_behavior
34
+ deprecator.behavior = old_behavior
32
35
  end
33
36
  end
34
37
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+
5
+ module ActiveSupport
6
+ module Testing
7
+ # Adds simple access to sample files called file fixtures.
8
+ # File fixtures are normal files stored in
9
+ # <tt>ActiveSupport::TestCase.file_fixture_path</tt>.
10
+ #
11
+ # File fixtures are represented as +Pathname+ objects.
12
+ # This makes it easy to extract specific information:
13
+ #
14
+ # file_fixture("example.txt").read # get the file's content
15
+ # file_fixture("example.mp3").size # get the file size
16
+ module FileFixtures
17
+ extend ActiveSupport::Concern
18
+
19
+ included do
20
+ class_attribute :file_fixture_path, instance_writer: false
21
+ end
22
+
23
+ # Returns a +Pathname+ to the fixture file named +fixture_name+.
24
+ #
25
+ # Raises +ArgumentError+ if +fixture_name+ can't be found.
26
+ def file_fixture(fixture_name)
27
+ path = Pathname.new(File.join(file_fixture_path, fixture_name))
28
+
29
+ if path.exist?
30
+ path
31
+ else
32
+ msg = "the directory '%s' does not contain a file named '%s'"
33
+ raise ArgumentError, msg % [file_fixture_path, fixture_name]
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,9 +1,9 @@
1
- require 'rbconfig'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module ActiveSupport
4
4
  module Testing
5
5
  module Isolation
6
- require 'thread'
6
+ require "thread"
7
7
 
8
8
  def self.included(klass) #:nodoc:
9
9
  klass.class_eval do
@@ -12,18 +12,7 @@ module ActiveSupport
12
12
  end
13
13
 
14
14
  def self.forking_env?
15
- !ENV["NO_FORK"] && ((RbConfig::CONFIG['host_os'] !~ /mswin|mingw/) && (RUBY_PLATFORM !~ /java/))
16
- end
17
-
18
- @@class_setup_mutex = Mutex.new
19
-
20
- def _run_class_setup # class setup method should only happen in parent
21
- @@class_setup_mutex.synchronize do
22
- unless defined?(@@ran_class_setup) || ENV['ISOLATION_TEST']
23
- self.class.setup if self.class.respond_to?(:setup)
24
- @@ran_class_setup = true
25
- end
26
- end
15
+ !ENV["NO_FORK"] && Process.respond_to?(:fork)
27
16
  end
28
17
 
29
18
  def run
@@ -43,14 +32,31 @@ module ActiveSupport
43
32
  pid = fork do
44
33
  read.close
45
34
  yield
46
- write.puts [Marshal.dump(self.dup)].pack("m")
35
+ begin
36
+ if error?
37
+ failures.map! { |e|
38
+ begin
39
+ Marshal.dump e
40
+ e
41
+ rescue TypeError
42
+ ex = Exception.new e.message
43
+ ex.set_backtrace e.backtrace
44
+ Minitest::UnexpectedError.new ex
45
+ end
46
+ }
47
+ end
48
+ test_result = defined?(Minitest::Result) ? Minitest::Result.from(self) : dup
49
+ result = Marshal.dump(test_result)
50
+ end
51
+
52
+ write.puts [result].pack("m")
47
53
  exit!
48
54
  end
49
55
 
50
56
  write.close
51
57
  result = read.read
52
58
  Process.wait2(pid)
53
- return result.unpack("m")[0]
59
+ result.unpack1("m")
54
60
  end
55
61
  end
56
62
 
@@ -64,24 +70,27 @@ module ActiveSupport
64
70
 
65
71
  if ENV["ISOLATION_TEST"]
66
72
  yield
73
+ test_result = defined?(Minitest::Result) ? Minitest::Result.from(self) : dup
67
74
  File.open(ENV["ISOLATION_OUTPUT"], "w") do |file|
68
- file.puts [Marshal.dump(self.dup)].pack("m")
75
+ file.puts [Marshal.dump(test_result)].pack("m")
69
76
  end
70
77
  exit!
71
78
  else
72
79
  Tempfile.open("isolation") do |tmpfile|
73
80
  env = {
74
- ISOLATION_TEST: self.class.name,
75
- ISOLATION_OUTPUT: tmpfile.path
81
+ "ISOLATION_TEST" => self.class.name,
82
+ "ISOLATION_OUTPUT" => tmpfile.path
76
83
  }
77
84
 
78
- load_paths = $-I.map {|p| "-I\"#{File.expand_path(p)}\"" }.join(" ")
79
- orig_args = ORIG_ARGV.join(" ")
80
- test_opts = "-n#{self.class.name}##{self.name}"
81
- command = "#{Gem.ruby} #{load_paths} #{$0} #{orig_args} #{test_opts}"
85
+ test_opts = "-n#{self.class.name}##{name}"
86
+
87
+ load_path_args = []
88
+ $-I.each do |p|
89
+ load_path_args << "-I"
90
+ load_path_args << File.expand_path(p)
91
+ end
82
92
 
83
- # IO.popen lets us pass env in a cross-platform way
84
- child = IO.popen([env, command])
93
+ child = IO.popen([env, Gem.ruby, *load_path_args, $0, *ORIG_ARGV, test_opts])
85
94
 
86
95
  begin
87
96
  Process.wait(child.pid)
@@ -89,7 +98,7 @@ module ActiveSupport
89
98
  nil
90
99
  end
91
100
 
92
- return tmpfile.read.unpack("m")[0]
101
+ return tmpfile.read.unpack1("m")
93
102
  end
94
103
  end
95
104
  end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "minitest/mock"
4
+
5
+ module ActiveSupport
6
+ module Testing
7
+ module MethodCallAssertions # :nodoc:
8
+ private
9
+ def assert_called(object, method_name, message = nil, times: 1, returns: nil)
10
+ times_called = 0
11
+
12
+ object.stub(method_name, proc { times_called += 1; returns }) { yield }
13
+
14
+ error = "Expected #{method_name} to be called #{times} times, " \
15
+ "but was called #{times_called} times"
16
+ error = "#{message}.\n#{error}" if message
17
+ assert_equal times, times_called, error
18
+ end
19
+
20
+ def assert_called_with(object, method_name, args, returns: nil)
21
+ mock = Minitest::Mock.new
22
+
23
+ if args.all? { |arg| arg.is_a?(Array) }
24
+ args.each { |arg| mock.expect(:call, returns, arg) }
25
+ else
26
+ mock.expect(:call, returns, args)
27
+ end
28
+
29
+ object.stub(method_name, mock) { yield }
30
+
31
+ mock.verify
32
+ end
33
+
34
+ def assert_not_called(object, method_name, message = nil, &block)
35
+ assert_called(object, method_name, message, times: 0, &block)
36
+ end
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
+
65
+ def stub_any_instance(klass, instance: klass.new)
66
+ klass.stub(:new, instance) { yield instance }
67
+ end
68
+ end
69
+ end
70
+ 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,5 +1,6 @@
1
- require 'active_support/concern'
2
- require 'active_support/callbacks'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/callbacks"
3
4
 
4
5
  module ActiveSupport
5
6
  module Testing
@@ -17,11 +18,10 @@ module ActiveSupport
17
18
  # end
18
19
  # end
19
20
  module SetupAndTeardown
20
- extend ActiveSupport::Concern
21
-
22
- included do
23
- include ActiveSupport::Callbacks
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
- run_callbacks :teardown
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
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ module Testing
5
+ module Stream #:nodoc:
6
+ private
7
+ def silence_stream(stream)
8
+ old_stream = stream.dup
9
+ stream.reopen(IO::NULL)
10
+ stream.sync = true
11
+ yield
12
+ ensure
13
+ stream.reopen(old_stream)
14
+ old_stream.close
15
+ end
16
+
17
+ def quietly
18
+ silence_stream(STDOUT) do
19
+ silence_stream(STDERR) do
20
+ yield
21
+ end
22
+ end
23
+ end
24
+
25
+ def capture(stream)
26
+ stream = stream.to_s
27
+ captured_stream = Tempfile.new(stream)
28
+ stream_io = eval("$#{stream}")
29
+ origin_stream = stream_io.dup
30
+ stream_io.reopen(captured_stream)
31
+
32
+ yield
33
+
34
+ stream_io.rewind
35
+ captured_stream.read
36
+ ensure
37
+ captured_stream.close
38
+ captured_stream.unlink
39
+ stream_io.reopen(origin_stream)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -1,3 +1,5 @@
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
@@ -8,7 +10,7 @@ module ActiveSupport
8
10
  def before_setup
9
11
  if tagged_logger && tagged_logger.info?
10
12
  heading = "#{self.class}: #{name}"
11
- divider = '-' * heading.size
13
+ divider = "-" * heading.size
12
14
  tagged_logger.info divider
13
15
  tagged_logger.info heading
14
16
  tagged_logger.info divider