activesupport 1.2.4 → 8.1.2

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.
Files changed (309) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +505 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +40 -0
  5. data/lib/active_support/actionable_error.rb +50 -0
  6. data/lib/active_support/all.rb +5 -0
  7. data/lib/active_support/array_inquirer.rb +50 -0
  8. data/lib/active_support/backtrace_cleaner.rb +234 -0
  9. data/lib/active_support/benchmark.rb +21 -0
  10. data/lib/active_support/benchmarkable.rb +53 -0
  11. data/lib/active_support/broadcast_logger.rb +238 -0
  12. data/lib/active_support/builder.rb +8 -0
  13. data/lib/active_support/cache/coder.rb +153 -0
  14. data/lib/active_support/cache/entry.rb +134 -0
  15. data/lib/active_support/cache/file_store.rb +244 -0
  16. data/lib/active_support/cache/mem_cache_store.rb +288 -0
  17. data/lib/active_support/cache/memory_store.rb +264 -0
  18. data/lib/active_support/cache/null_store.rb +62 -0
  19. data/lib/active_support/cache/redis_cache_store.rb +498 -0
  20. data/lib/active_support/cache/serializer_with_fallback.rb +152 -0
  21. data/lib/active_support/cache/strategy/local_cache.rb +246 -0
  22. data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
  23. data/lib/active_support/cache.rb +1170 -0
  24. data/lib/active_support/callbacks.rb +960 -0
  25. data/lib/active_support/class_attribute.rb +33 -0
  26. data/lib/active_support/code_generator.rb +79 -0
  27. data/lib/active_support/concern.rb +217 -0
  28. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
  29. data/lib/active_support/concurrency/null_lock.rb +13 -0
  30. data/lib/active_support/concurrency/share_lock.rb +225 -0
  31. data/lib/active_support/concurrency/thread_monitor.rb +55 -0
  32. data/lib/active_support/configurable.rb +193 -0
  33. data/lib/active_support/configuration_file.rb +60 -0
  34. data/lib/active_support/continuous_integration.rb +145 -0
  35. data/lib/active_support/core_ext/array/access.rb +100 -0
  36. data/lib/active_support/core_ext/array/conversions.rb +209 -26
  37. data/lib/active_support/core_ext/array/extract.rb +21 -0
  38. data/lib/active_support/core_ext/array/extract_options.rb +31 -0
  39. data/lib/active_support/core_ext/array/grouping.rb +109 -0
  40. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  41. data/lib/active_support/core_ext/array/wrap.rb +48 -0
  42. data/lib/active_support/core_ext/array.rb +8 -4
  43. data/lib/active_support/core_ext/benchmark.rb +6 -0
  44. data/lib/active_support/core_ext/big_decimal/conversions.rb +14 -0
  45. data/lib/active_support/core_ext/big_decimal.rb +3 -0
  46. data/lib/active_support/core_ext/class/attribute.rb +137 -0
  47. data/lib/active_support/core_ext/class/attribute_accessors.rb +6 -0
  48. data/lib/active_support/core_ext/class/subclasses.rb +24 -0
  49. data/lib/active_support/core_ext/class.rb +4 -0
  50. data/lib/active_support/core_ext/date/acts_like.rb +10 -0
  51. data/lib/active_support/core_ext/date/blank.rb +18 -0
  52. data/lib/active_support/core_ext/date/calculations.rb +161 -0
  53. data/lib/active_support/core_ext/date/conversions.rb +95 -28
  54. data/lib/active_support/core_ext/date/zones.rb +8 -0
  55. data/lib/active_support/core_ext/date.rb +6 -5
  56. data/lib/active_support/core_ext/date_and_time/calculations.rb +374 -0
  57. data/lib/active_support/core_ext/date_and_time/compatibility.rb +23 -0
  58. data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
  59. data/lib/active_support/core_ext/date_time/acts_like.rb +16 -0
  60. data/lib/active_support/core_ext/date_time/blank.rb +18 -0
  61. data/lib/active_support/core_ext/date_time/calculations.rb +215 -0
  62. data/lib/active_support/core_ext/date_time/compatibility.rb +16 -0
  63. data/lib/active_support/core_ext/date_time/conversions.rb +108 -0
  64. data/lib/active_support/core_ext/date_time.rb +7 -0
  65. data/lib/active_support/core_ext/digest/uuid.rb +76 -0
  66. data/lib/active_support/core_ext/digest.rb +3 -0
  67. data/lib/active_support/core_ext/enumerable.rb +277 -7
  68. data/lib/active_support/core_ext/erb/util.rb +201 -0
  69. data/lib/active_support/core_ext/file/atomic.rb +72 -0
  70. data/lib/active_support/core_ext/file.rb +3 -0
  71. data/lib/active_support/core_ext/hash/conversions.rb +262 -0
  72. data/lib/active_support/core_ext/hash/deep_merge.rb +43 -0
  73. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  74. data/lib/active_support/core_ext/hash/except.rb +12 -0
  75. data/lib/active_support/core_ext/hash/indifferent_access.rb +19 -55
  76. data/lib/active_support/core_ext/hash/keys.rb +134 -44
  77. data/lib/active_support/core_ext/hash/reverse_merge.rb +22 -22
  78. data/lib/active_support/core_ext/hash/slice.rb +27 -0
  79. data/lib/active_support/core_ext/hash.rb +9 -8
  80. data/lib/active_support/core_ext/integer/inflections.rb +29 -13
  81. data/lib/active_support/core_ext/integer/multiple.rb +12 -0
  82. data/lib/active_support/core_ext/integer/time.rb +22 -0
  83. data/lib/active_support/core_ext/integer.rb +4 -6
  84. data/lib/active_support/core_ext/kernel/concern.rb +14 -0
  85. data/lib/active_support/core_ext/kernel/reporting.rb +45 -0
  86. data/lib/active_support/core_ext/kernel/singleton_class.rb +8 -0
  87. data/lib/active_support/core_ext/kernel.rb +4 -78
  88. data/lib/active_support/core_ext/load_error.rb +6 -35
  89. data/lib/active_support/core_ext/module/aliasing.rb +31 -0
  90. data/lib/active_support/core_ext/module/anonymous.rb +30 -0
  91. data/lib/active_support/core_ext/module/attr_internal.rb +48 -0
  92. data/lib/active_support/core_ext/module/attribute_accessors.rb +214 -0
  93. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +175 -0
  94. data/lib/active_support/core_ext/module/concerning.rb +140 -0
  95. data/lib/active_support/core_ext/module/delegation.rb +225 -0
  96. data/lib/active_support/core_ext/module/deprecation.rb +25 -0
  97. data/lib/active_support/core_ext/module/introspection.rb +65 -0
  98. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  99. data/lib/active_support/core_ext/module/remove_method.rb +17 -0
  100. data/lib/active_support/core_ext/module.rb +13 -0
  101. data/lib/active_support/core_ext/name_error.rb +59 -0
  102. data/lib/active_support/core_ext/numeric/bytes.rb +73 -42
  103. data/lib/active_support/core_ext/numeric/conversions.rb +145 -0
  104. data/lib/active_support/core_ext/numeric/time.rb +64 -57
  105. data/lib/active_support/core_ext/numeric.rb +4 -6
  106. data/lib/active_support/core_ext/object/acts_like.rb +45 -0
  107. data/lib/active_support/core_ext/object/blank.rb +199 -0
  108. data/lib/active_support/core_ext/object/conversions.rb +6 -0
  109. data/lib/active_support/core_ext/object/deep_dup.rb +71 -0
  110. data/lib/active_support/core_ext/object/duplicable.rb +69 -0
  111. data/lib/active_support/core_ext/object/inclusion.rb +37 -0
  112. data/lib/active_support/core_ext/object/instance_variables.rb +32 -0
  113. data/lib/active_support/core_ext/object/json.rb +267 -0
  114. data/lib/active_support/core_ext/object/to_param.rb +3 -0
  115. data/lib/active_support/core_ext/object/to_query.rb +93 -0
  116. data/lib/active_support/core_ext/object/try.rb +158 -0
  117. data/lib/active_support/core_ext/object/with.rb +46 -0
  118. data/lib/active_support/core_ext/object/with_options.rb +101 -0
  119. data/lib/active_support/core_ext/object.rb +17 -0
  120. data/lib/active_support/core_ext/pathname/blank.rb +20 -0
  121. data/lib/active_support/core_ext/pathname/existence.rb +23 -0
  122. data/lib/active_support/core_ext/pathname.rb +4 -0
  123. data/lib/active_support/core_ext/range/compare_range.rb +57 -0
  124. data/lib/active_support/core_ext/range/conversions.rb +58 -17
  125. data/lib/active_support/core_ext/range/overlap.rb +40 -0
  126. data/lib/active_support/core_ext/range/sole.rb +17 -0
  127. data/lib/active_support/core_ext/range.rb +5 -4
  128. data/lib/active_support/core_ext/regexp.rb +14 -0
  129. data/lib/active_support/core_ext/securerandom.rb +57 -0
  130. data/lib/active_support/core_ext/string/access.rb +93 -56
  131. data/lib/active_support/core_ext/string/behavior.rb +8 -0
  132. data/lib/active_support/core_ext/string/conversions.rb +57 -16
  133. data/lib/active_support/core_ext/string/exclude.rb +13 -0
  134. data/lib/active_support/core_ext/string/filters.rb +151 -0
  135. data/lib/active_support/core_ext/string/indent.rb +45 -0
  136. data/lib/active_support/core_ext/string/inflections.rb +297 -54
  137. data/lib/active_support/core_ext/string/inquiry.rb +16 -0
  138. data/lib/active_support/core_ext/string/multibyte.rb +67 -0
  139. data/lib/active_support/core_ext/string/output_safety.rb +235 -0
  140. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -18
  141. data/lib/active_support/core_ext/string/strip.rb +27 -0
  142. data/lib/active_support/core_ext/string/zones.rb +16 -0
  143. data/lib/active_support/core_ext/string.rb +14 -10
  144. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
  145. data/lib/active_support/core_ext/symbol.rb +3 -0
  146. data/lib/active_support/core_ext/thread/backtrace/location.rb +7 -0
  147. data/lib/active_support/core_ext/time/acts_like.rb +10 -0
  148. data/lib/active_support/core_ext/time/calculations.rb +358 -153
  149. data/lib/active_support/core_ext/time/compatibility.rb +15 -0
  150. data/lib/active_support/core_ext/time/conversions.rb +69 -30
  151. data/lib/active_support/core_ext/time/zones.rb +97 -0
  152. data/lib/active_support/core_ext/time.rb +6 -6
  153. data/lib/active_support/core_ext.rb +5 -1
  154. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  155. data/lib/active_support/current_attributes.rb +243 -0
  156. data/lib/active_support/deep_mergeable.rb +53 -0
  157. data/lib/active_support/delegation.rb +183 -0
  158. data/lib/active_support/dependencies/autoload.rb +72 -0
  159. data/lib/active_support/dependencies/interlock.rb +55 -0
  160. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  161. data/lib/active_support/dependencies.rb +84 -222
  162. data/lib/active_support/deprecation/behaviors.rb +148 -0
  163. data/lib/active_support/deprecation/constant_accessor.rb +74 -0
  164. data/lib/active_support/deprecation/deprecators.rb +104 -0
  165. data/lib/active_support/deprecation/disallowed.rb +54 -0
  166. data/lib/active_support/deprecation/method_wrappers.rb +68 -0
  167. data/lib/active_support/deprecation/proxy_wrappers.rb +189 -0
  168. data/lib/active_support/deprecation/reporting.rb +162 -0
  169. data/lib/active_support/deprecation.rb +81 -0
  170. data/lib/active_support/deprecator.rb +7 -0
  171. data/lib/active_support/descendants_tracker.rb +112 -0
  172. data/lib/active_support/digest.rb +22 -0
  173. data/lib/active_support/duration/iso8601_parser.rb +123 -0
  174. data/lib/active_support/duration/iso8601_serializer.rb +64 -0
  175. data/lib/active_support/duration.rb +524 -0
  176. data/lib/active_support/editor.rb +70 -0
  177. data/lib/active_support/encrypted_configuration.rb +126 -0
  178. data/lib/active_support/encrypted_file.rb +133 -0
  179. data/lib/active_support/environment_inquirer.rb +40 -0
  180. data/lib/active_support/error_reporter/test_helper.rb +15 -0
  181. data/lib/active_support/error_reporter.rb +318 -0
  182. data/lib/active_support/event_reporter/test_helper.rb +32 -0
  183. data/lib/active_support/event_reporter.rb +592 -0
  184. data/lib/active_support/evented_file_update_checker.rb +185 -0
  185. data/lib/active_support/execution_context/test_helper.rb +13 -0
  186. data/lib/active_support/execution_context.rb +110 -0
  187. data/lib/active_support/execution_wrapper.rb +150 -0
  188. data/lib/active_support/executor/test_helper.rb +7 -0
  189. data/lib/active_support/executor.rb +8 -0
  190. data/lib/active_support/file_update_checker.rb +166 -0
  191. data/lib/active_support/fork_tracker.rb +43 -0
  192. data/lib/active_support/gem_version.rb +17 -0
  193. data/lib/active_support/gzip.rb +41 -0
  194. data/lib/active_support/hash_with_indifferent_access.rb +464 -0
  195. data/lib/active_support/html_safe_translation.rb +56 -0
  196. data/lib/active_support/i18n.rb +17 -0
  197. data/lib/active_support/i18n_railtie.rb +140 -0
  198. data/lib/active_support/inflections.rb +68 -49
  199. data/lib/active_support/inflector/inflections.rb +290 -0
  200. data/lib/active_support/inflector/methods.rb +387 -0
  201. data/lib/active_support/inflector/transliterate.rb +147 -0
  202. data/lib/active_support/inflector.rb +7 -164
  203. data/lib/active_support/isolated_execution_state.rb +76 -0
  204. data/lib/active_support/json/decoding.rb +78 -0
  205. data/lib/active_support/json/encoding.rb +256 -0
  206. data/lib/active_support/json.rb +4 -0
  207. data/lib/active_support/key_generator.rb +66 -0
  208. data/lib/active_support/lazy_load_hooks.rb +107 -0
  209. data/lib/active_support/locale/en.rb +33 -0
  210. data/lib/active_support/locale/en.yml +141 -0
  211. data/lib/active_support/log_subscriber/test_helper.rb +106 -0
  212. data/lib/active_support/log_subscriber.rb +188 -0
  213. data/lib/active_support/logger.rb +55 -0
  214. data/lib/active_support/logger_silence.rb +21 -0
  215. data/lib/active_support/logger_thread_safe_level.rb +50 -0
  216. data/lib/active_support/message_encryptor.rb +374 -0
  217. data/lib/active_support/message_encryptors.rb +193 -0
  218. data/lib/active_support/message_pack/cache_serializer.rb +23 -0
  219. data/lib/active_support/message_pack/extensions.rb +310 -0
  220. data/lib/active_support/message_pack/serializer.rb +63 -0
  221. data/lib/active_support/message_pack.rb +50 -0
  222. data/lib/active_support/message_verifier.rb +377 -0
  223. data/lib/active_support/message_verifiers.rb +189 -0
  224. data/lib/active_support/messages/codec.rb +65 -0
  225. data/lib/active_support/messages/metadata.rb +146 -0
  226. data/lib/active_support/messages/rotation_configuration.rb +23 -0
  227. data/lib/active_support/messages/rotation_coordinator.rb +102 -0
  228. data/lib/active_support/messages/rotator.rb +69 -0
  229. data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
  230. data/lib/active_support/multibyte/chars.rb +188 -0
  231. data/lib/active_support/multibyte/unicode.rb +42 -0
  232. data/lib/active_support/multibyte.rb +27 -0
  233. data/lib/active_support/notifications/fanout.rb +467 -0
  234. data/lib/active_support/notifications/instrumenter.rb +240 -0
  235. data/lib/active_support/notifications.rb +281 -0
  236. data/lib/active_support/number_helper/number_converter.rb +190 -0
  237. data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
  238. data/lib/active_support/number_helper/number_to_delimited_converter.rb +30 -0
  239. data/lib/active_support/number_helper/number_to_human_converter.rb +69 -0
  240. data/lib/active_support/number_helper/number_to_human_size_converter.rb +60 -0
  241. data/lib/active_support/number_helper/number_to_percentage_converter.rb +16 -0
  242. data/lib/active_support/number_helper/number_to_phone_converter.rb +60 -0
  243. data/lib/active_support/number_helper/number_to_rounded_converter.rb +59 -0
  244. data/lib/active_support/number_helper/rounding_helper.rb +46 -0
  245. data/lib/active_support/number_helper.rb +479 -0
  246. data/lib/active_support/option_merger.rb +38 -0
  247. data/lib/active_support/ordered_hash.rb +50 -0
  248. data/lib/active_support/ordered_options.rb +141 -25
  249. data/lib/active_support/parameter_filter.rb +157 -0
  250. data/lib/active_support/rails.rb +26 -0
  251. data/lib/active_support/railtie.rb +180 -0
  252. data/lib/active_support/reloader.rb +138 -0
  253. data/lib/active_support/rescuable.rb +176 -0
  254. data/lib/active_support/secure_compare_rotator.rb +58 -0
  255. data/lib/active_support/security_utils.rb +38 -0
  256. data/lib/active_support/string_inquirer.rb +35 -0
  257. data/lib/active_support/structured_event_subscriber.rb +99 -0
  258. data/lib/active_support/subscriber.rb +141 -0
  259. data/lib/active_support/syntax_error_proxy.rb +67 -0
  260. data/lib/active_support/tagged_logging.rb +157 -0
  261. data/lib/active_support/test_case.rb +365 -0
  262. data/lib/active_support/testing/assertions.rb +369 -0
  263. data/lib/active_support/testing/autorun.rb +10 -0
  264. data/lib/active_support/testing/constant_lookup.rb +51 -0
  265. data/lib/active_support/testing/constant_stubbing.rb +54 -0
  266. data/lib/active_support/testing/declarative.rb +28 -0
  267. data/lib/active_support/testing/deprecation.rb +82 -0
  268. data/lib/active_support/testing/error_reporter_assertions.rb +124 -0
  269. data/lib/active_support/testing/event_reporter_assertions.rb +227 -0
  270. data/lib/active_support/testing/file_fixtures.rb +38 -0
  271. data/lib/active_support/testing/isolation.rb +121 -0
  272. data/lib/active_support/testing/method_call_assertions.rb +69 -0
  273. data/lib/active_support/testing/notification_assertions.rb +92 -0
  274. data/lib/active_support/testing/parallelization/server.rb +98 -0
  275. data/lib/active_support/testing/parallelization/worker.rb +107 -0
  276. data/lib/active_support/testing/parallelization.rb +79 -0
  277. data/lib/active_support/testing/parallelize_executor.rb +81 -0
  278. data/lib/active_support/testing/setup_and_teardown.rb +57 -0
  279. data/lib/active_support/testing/stream.rb +41 -0
  280. data/lib/active_support/testing/tagged_logging.rb +27 -0
  281. data/lib/active_support/testing/tests_without_assertions.rb +19 -0
  282. data/lib/active_support/testing/time_helpers.rb +273 -0
  283. data/lib/active_support/time.rb +20 -0
  284. data/lib/active_support/time_with_zone.rb +613 -0
  285. data/lib/active_support/values/time_zone.rb +599 -158
  286. data/lib/active_support/version.rb +7 -6
  287. data/lib/active_support/xml_mini/jdom.rb +175 -0
  288. data/lib/active_support/xml_mini/libxml.rb +80 -0
  289. data/lib/active_support/xml_mini/libxmlsax.rb +83 -0
  290. data/lib/active_support/xml_mini/nokogiri.rb +83 -0
  291. data/lib/active_support/xml_mini/nokogirisax.rb +86 -0
  292. data/lib/active_support/xml_mini/rexml.rb +137 -0
  293. data/lib/active_support/xml_mini.rb +212 -0
  294. data/lib/active_support.rb +122 -10
  295. metadata +524 -93
  296. data/CHANGELOG +0 -283
  297. data/lib/active_support/binding_of_caller.rb +0 -84
  298. data/lib/active_support/breakpoint.rb +0 -523
  299. data/lib/active_support/class_attribute_accessors.rb +0 -57
  300. data/lib/active_support/class_inheritable_attributes.rb +0 -117
  301. data/lib/active_support/clean_logger.rb +0 -36
  302. data/lib/active_support/core_ext/blank.rb +0 -38
  303. data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +0 -14
  304. data/lib/active_support/core_ext/cgi.rb +0 -5
  305. data/lib/active_support/core_ext/exception.rb +0 -29
  306. data/lib/active_support/core_ext/integer/even_odd.rb +0 -24
  307. data/lib/active_support/core_ext/object_and_class.rb +0 -44
  308. data/lib/active_support/module_attribute_accessors.rb +0 -57
  309. data/lib/active_support/whiny_nil.rb +0 -38
@@ -0,0 +1,98 @@
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
+ PrerecordResultClass = Struct.new(:name)
10
+
11
+ class Server
12
+ include DRb::DRbUndumped
13
+
14
+ def initialize
15
+ @queue = Queue.new
16
+ @active_workers = Concurrent::Map.new
17
+ @worker_pids = Concurrent::Map.new
18
+ @in_flight = Concurrent::Map.new
19
+ end
20
+
21
+ def record(reporter, result)
22
+ raise DRb::DRbConnError if result.is_a?(DRb::DRbUnknown)
23
+
24
+ @in_flight.delete([result.klass, result.name])
25
+
26
+ reporter.synchronize do
27
+ reporter.prerecord(PrerecordResultClass.new(result.klass), result.name)
28
+ reporter.record(result)
29
+ end
30
+ end
31
+
32
+ def <<(o)
33
+ o[2] = DRbObject.new(o[2]) if o
34
+ @queue << o
35
+ end
36
+
37
+ def pop
38
+ if test = @queue.pop
39
+ @in_flight[[test[0].to_s, test[1]]] = test
40
+ test
41
+ end
42
+ end
43
+
44
+ def start_worker(worker_id, worker_pid)
45
+ @active_workers[worker_id] = true
46
+ @worker_pids[worker_id] = worker_pid
47
+ end
48
+
49
+ def stop_worker(worker_id, worker_pid)
50
+ @active_workers.delete(worker_id)
51
+ @worker_pids.delete(worker_id)
52
+ end
53
+
54
+ def remove_dead_workers(dead_pids)
55
+ dead_pids.each do |dead_pid|
56
+ worker_id = @worker_pids.key(dead_pid)
57
+ if worker_id
58
+ @active_workers.delete(worker_id)
59
+ @worker_pids.delete(worker_id)
60
+ end
61
+ end
62
+ end
63
+
64
+ def active_workers?
65
+ @active_workers.size > 0
66
+ end
67
+
68
+ def interrupt
69
+ @queue.clear
70
+ end
71
+
72
+ def shutdown
73
+ # Wait for initial queue to drain
74
+ while @queue.length != 0
75
+ sleep 0.1
76
+ end
77
+
78
+ @queue.close
79
+
80
+ # Wait until all workers have finished
81
+ while active_workers?
82
+ sleep 0.1
83
+ end
84
+
85
+ @in_flight.values.each do |(klass, name, reporter)|
86
+ result = Minitest::Result.from(klass.new(name))
87
+ error = RuntimeError.new("result not reported")
88
+ error.set_backtrace([""])
89
+ result.failures << Minitest::UnexpectedError.new(error)
90
+ reporter.synchronize do
91
+ reporter.record(result)
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,107 @@
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, Process.pid)
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, Process.pid)
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 = if Minitest.respond_to? :run_one_method then
50
+ Minitest.run_one_method klass, method
51
+ else
52
+ klass.new(method).run
53
+ end
54
+
55
+ safe_record(reporter, result)
56
+ end
57
+
58
+ def safe_record(reporter, result)
59
+ add_setup_exception(result) if @setup_exception
60
+
61
+ begin
62
+ @queue.record(reporter, result)
63
+ rescue DRb::DRbConnError
64
+ result.failures.map! do |failure|
65
+ if failure.respond_to?(:error)
66
+ # minitest >5.14.0
67
+ error = DRb::DRbRemoteError.new(failure.error)
68
+ else
69
+ error = DRb::DRbRemoteError.new(failure.exception)
70
+ end
71
+ Minitest::UnexpectedError.new(error)
72
+ end
73
+ @queue.record(reporter, result)
74
+ rescue Interrupt
75
+ @queue.interrupt
76
+ raise
77
+ end
78
+
79
+ set_process_title("(idle)")
80
+ end
81
+
82
+ def after_fork
83
+ ActiveSupport::TestCase.parallel_worker_id = @number
84
+
85
+ Parallelization.after_fork_hooks.each do |cb|
86
+ cb.call(@number)
87
+ end
88
+ end
89
+
90
+ def run_cleanup
91
+ Parallelization.run_cleanup_hooks.each do |cb|
92
+ cb.call(@number)
93
+ end
94
+ end
95
+
96
+ private
97
+ def add_setup_exception(result)
98
+ result.failures.prepend Minitest::UnexpectedError.new(@setup_exception)
99
+ end
100
+
101
+ def set_process_title(status)
102
+ Process.setproctitle("Rails test worker #{@number} - #{status}")
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,79 @@
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
+ @@before_fork_hooks = []
13
+
14
+ def self.before_fork_hook(&blk)
15
+ @@before_fork_hooks << blk
16
+ end
17
+
18
+ cattr_reader :before_fork_hooks
19
+
20
+ @@after_fork_hooks = []
21
+
22
+ def self.after_fork_hook(&blk)
23
+ @@after_fork_hooks << blk
24
+ end
25
+
26
+ cattr_reader :after_fork_hooks
27
+
28
+ @@run_cleanup_hooks = []
29
+
30
+ def self.run_cleanup_hook(&blk)
31
+ @@run_cleanup_hooks << blk
32
+ end
33
+
34
+ cattr_reader :run_cleanup_hooks
35
+
36
+ def initialize(worker_count)
37
+ @worker_count = worker_count
38
+ @queue_server = Server.new
39
+ @worker_pool = []
40
+ @url = DRb.start_service("drbunix:", @queue_server).uri
41
+ end
42
+
43
+ def before_fork
44
+ Parallelization.before_fork_hooks.each(&:call)
45
+ end
46
+
47
+ def start
48
+ before_fork
49
+ @worker_pool = @worker_count.times.map do |worker|
50
+ Worker.new(worker, @url).start
51
+ end
52
+ end
53
+
54
+ def <<(work)
55
+ @queue_server << work
56
+ end
57
+
58
+ def size
59
+ @worker_count
60
+ end
61
+
62
+ def shutdown
63
+ dead_worker_pids = @worker_pool.filter_map do |pid|
64
+ Process.waitpid(pid, Process::WNOHANG)
65
+ rescue Errno::ECHILD
66
+ pid
67
+ end
68
+ @queue_server.remove_dead_workers(dead_worker_pids)
69
+
70
+ @queue_server.shutdown
71
+ @worker_pool.each do |pid|
72
+ Process.waitpid(pid)
73
+ rescue Errno::ECHILD
74
+ nil
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ module Testing
5
+ class ParallelizeExecutor # :nodoc:
6
+ attr_reader :size, :parallelize_with, :threshold
7
+
8
+ def initialize(size:, with:, threshold: ActiveSupport.test_parallelization_threshold)
9
+ @size = size
10
+ @parallelize_with = with
11
+ @threshold = threshold
12
+ @parallelized = false
13
+ end
14
+
15
+ def start
16
+ parallelize if should_parallelize?
17
+ show_execution_info
18
+
19
+ parallel_executor.start if parallelized?
20
+ end
21
+
22
+ def <<(work)
23
+ parallel_executor << work if parallelized?
24
+ end
25
+
26
+ def shutdown
27
+ parallel_executor.shutdown if parallelized?
28
+ end
29
+
30
+ private
31
+ def parallel_executor
32
+ @parallel_executor ||= build_parallel_executor
33
+ end
34
+
35
+ def build_parallel_executor
36
+ case parallelize_with
37
+ when :processes
38
+ Testing::Parallelization.new(size)
39
+ when :threads
40
+ ActiveSupport::TestCase.lock_threads = false if defined?(ActiveSupport::TestCase.lock_threads)
41
+ Minitest::Parallel::Executor.new(size)
42
+ else
43
+ raise ArgumentError, "#{parallelize_with} is not a supported parallelization executor."
44
+ end
45
+ end
46
+
47
+ def parallelize
48
+ @parallelized = true
49
+ Minitest::Test.parallelize_me!
50
+ end
51
+
52
+ def parallelized?
53
+ @parallelized
54
+ end
55
+
56
+ def should_parallelize?
57
+ (ENV["PARALLEL_WORKERS"] || tests_count > threshold) && many_workers?
58
+ end
59
+
60
+ def many_workers?
61
+ size > 1
62
+ end
63
+
64
+ def tests_count
65
+ @tests_count ||= Minitest::Runnable.runnables.sum { |runnable| runnable.runnable_methods.size }
66
+ end
67
+
68
+ def show_execution_info
69
+ puts execution_info
70
+ end
71
+
72
+ def execution_info
73
+ if parallelized?
74
+ "Running #{tests_count} tests in parallel using #{parallel_executor.size} #{parallelize_with}"
75
+ elsif many_workers?
76
+ "Running #{tests_count} tests in a single process (parallelization threshold is #{threshold})"
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/callbacks"
4
+
5
+ module ActiveSupport
6
+ module Testing
7
+ # Adds support for +setup+ and +teardown+ callbacks.
8
+ # These callbacks serve as a replacement to overwriting the
9
+ # <tt>#setup</tt> and <tt>#teardown</tt> methods of your TestCase.
10
+ #
11
+ # class ExampleTest < ActiveSupport::TestCase
12
+ # setup do
13
+ # # ...
14
+ # end
15
+ #
16
+ # teardown do
17
+ # # ...
18
+ # end
19
+ # end
20
+ module SetupAndTeardown
21
+ def self.prepended(klass)
22
+ klass.include ActiveSupport::Callbacks
23
+ klass.define_callbacks :setup, :teardown
24
+ klass.extend ClassMethods
25
+ end
26
+
27
+ module ClassMethods
28
+ # Add a callback, which runs before <tt>TestCase#setup</tt>.
29
+ def setup(*args, &block)
30
+ set_callback(:setup, :before, *args, &block)
31
+ end
32
+
33
+ # Add a callback, which runs after <tt>TestCase#teardown</tt>.
34
+ def teardown(*args, &block)
35
+ set_callback(:teardown, :after, *args, &block)
36
+ end
37
+ end
38
+
39
+ def before_setup # :nodoc:
40
+ super
41
+ run_callbacks :setup
42
+ end
43
+
44
+ def after_teardown # :nodoc:
45
+ begin
46
+ run_callbacks :teardown
47
+ rescue => e
48
+ self.failures << Minitest::UnexpectedError.new(e)
49
+ rescue Minitest::Assertion => e
50
+ self.failures << e
51
+ end
52
+
53
+ super
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,41 @@
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(&block)
18
+ silence_stream(STDOUT) do
19
+ silence_stream(STDERR, &block)
20
+ end
21
+ end
22
+
23
+ def capture(stream)
24
+ stream = stream.to_s
25
+ captured_stream = Tempfile.new(stream)
26
+ stream_io = eval("$#{stream}", binding, __FILE__, __LINE__)
27
+ origin_stream = stream_io.dup
28
+ stream_io.reopen(captured_stream)
29
+
30
+ yield
31
+
32
+ stream_io.rewind
33
+ captured_stream.read
34
+ ensure
35
+ captured_stream.close
36
+ captured_stream.unlink
37
+ stream_io.reopen(origin_stream)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ module Testing
5
+ # Logs a "PostsControllerTest: test name" heading before each test to
6
+ # make test.log easier to search and follow along with.
7
+ module TaggedLogging # :nodoc:
8
+ attr_writer :tagged_logger
9
+
10
+ def before_setup
11
+ if tagged_logger && tagged_logger.info?
12
+ heading = "#{self.class}: #{name}"
13
+ divider = "-" * heading.size
14
+ tagged_logger.info divider
15
+ tagged_logger.info heading
16
+ tagged_logger.info divider
17
+ end
18
+ super
19
+ end
20
+
21
+ private
22
+ def tagged_logger
23
+ @tagged_logger ||= (defined?(Rails.logger) && Rails.logger)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -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.expand_path(file)}:#{line}"
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end