activesupport 4.0.12 → 7.0.2.4

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 (295) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +249 -501
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +10 -5
  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 +41 -13
  9. data/lib/active_support/benchmarkable.rb +7 -15
  10. data/lib/active_support/builder.rb +3 -1
  11. data/lib/active_support/cache/file_store.rb +96 -74
  12. data/lib/active_support/cache/mem_cache_store.rb +211 -103
  13. data/lib/active_support/cache/memory_store.rb +90 -58
  14. data/lib/active_support/cache/null_store.rb +19 -7
  15. data/lib/active_support/cache/redis_cache_store.rb +468 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +86 -83
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
  18. data/lib/active_support/cache.rb +580 -241
  19. data/lib/active_support/callbacks.rb +812 -425
  20. data/lib/active_support/code_generator.rb +65 -0
  21. data/lib/active_support/concern.rb +103 -14
  22. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +33 -0
  23. data/lib/active_support/concurrency/share_lock.rb +226 -0
  24. data/lib/active_support/configurable.rb +21 -19
  25. data/lib/active_support/configuration_file.rb +51 -0
  26. data/lib/active_support/core_ext/array/access.rb +47 -1
  27. data/lib/active_support/core_ext/array/conversions.rb +35 -44
  28. data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
  29. data/lib/active_support/core_ext/array/extract.rb +21 -0
  30. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  31. data/lib/active_support/core_ext/array/grouping.rb +26 -16
  32. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  33. data/lib/active_support/core_ext/array/wrap.rb +7 -4
  34. data/lib/active_support/core_ext/array.rb +10 -7
  35. data/lib/active_support/core_ext/benchmark.rb +5 -3
  36. data/lib/active_support/core_ext/big_decimal/conversions.rb +9 -26
  37. data/lib/active_support/core_ext/big_decimal.rb +3 -1
  38. data/lib/active_support/core_ext/class/attribute.rb +52 -49
  39. data/lib/active_support/core_ext/class/attribute_accessors.rb +5 -169
  40. data/lib/active_support/core_ext/class/subclasses.rb +25 -26
  41. data/lib/active_support/core_ext/class.rb +4 -4
  42. data/lib/active_support/core_ext/date/acts_like.rb +3 -1
  43. data/lib/active_support/core_ext/date/blank.rb +14 -0
  44. data/lib/active_support/core_ext/date/calculations.rb +31 -18
  45. data/lib/active_support/core_ext/date/conversions.rb +43 -32
  46. data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
  47. data/lib/active_support/core_ext/date/zones.rb +5 -34
  48. data/lib/active_support/core_ext/date.rb +7 -4
  49. data/lib/active_support/core_ext/date_and_time/calculations.rb +198 -66
  50. data/lib/active_support/core_ext/date_and_time/compatibility.rb +31 -0
  51. data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
  52. data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
  53. data/lib/active_support/core_ext/date_time/blank.rb +14 -0
  54. data/lib/active_support/core_ext/date_time/calculations.rb +79 -38
  55. data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
  56. data/lib/active_support/core_ext/date_time/conversions.rb +31 -26
  57. data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
  58. data/lib/active_support/core_ext/date_time.rb +8 -4
  59. data/lib/active_support/core_ext/digest/uuid.rb +79 -0
  60. data/lib/active_support/core_ext/digest.rb +3 -0
  61. data/lib/active_support/core_ext/enumerable.rb +249 -17
  62. data/lib/active_support/core_ext/file/atomic.rb +41 -32
  63. data/lib/active_support/core_ext/file.rb +3 -1
  64. data/lib/active_support/core_ext/hash/conversions.rb +71 -49
  65. data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
  66. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  67. data/lib/active_support/core_ext/hash/except.rb +14 -5
  68. data/lib/active_support/core_ext/hash/indifferent_access.rb +5 -3
  69. data/lib/active_support/core_ext/hash/keys.rb +39 -56
  70. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  71. data/lib/active_support/core_ext/hash/slice.rb +8 -23
  72. data/lib/active_support/core_ext/hash.rb +10 -8
  73. data/lib/active_support/core_ext/integer/inflections.rb +3 -1
  74. data/lib/active_support/core_ext/integer/multiple.rb +3 -1
  75. data/lib/active_support/core_ext/integer/time.rb +11 -33
  76. data/lib/active_support/core_ext/integer.rb +5 -3
  77. data/lib/active_support/core_ext/kernel/concern.rb +14 -0
  78. data/lib/active_support/core_ext/kernel/reporting.rb +9 -78
  79. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  80. data/lib/active_support/core_ext/kernel.rb +5 -4
  81. data/lib/active_support/core_ext/load_error.rb +5 -21
  82. data/lib/active_support/core_ext/module/aliasing.rb +6 -44
  83. data/lib/active_support/core_ext/module/anonymous.rb +12 -1
  84. data/lib/active_support/core_ext/module/attr_internal.rb +8 -8
  85. data/lib/active_support/core_ext/module/attribute_accessors.rb +186 -44
  86. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +157 -0
  87. data/lib/active_support/core_ext/module/concerning.rb +140 -0
  88. data/lib/active_support/core_ext/module/delegation.rb +172 -45
  89. data/lib/active_support/core_ext/module/deprecation.rb +3 -3
  90. data/lib/active_support/core_ext/module/introspection.rb +23 -38
  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 -10
  94. data/lib/active_support/core_ext/name_error.rb +45 -4
  95. data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
  96. data/lib/active_support/core_ext/numeric/conversions.rb +135 -127
  97. data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
  98. data/lib/active_support/core_ext/numeric/time.rb +37 -50
  99. data/lib/active_support/core_ext/numeric.rb +6 -3
  100. data/lib/active_support/core_ext/object/acts_like.rb +41 -6
  101. data/lib/active_support/core_ext/object/blank.rb +70 -20
  102. data/lib/active_support/core_ext/object/conversions.rb +6 -4
  103. data/lib/active_support/core_ext/object/deep_dup.rb +19 -10
  104. data/lib/active_support/core_ext/object/duplicable.rb +17 -47
  105. data/lib/active_support/core_ext/object/inclusion.rb +18 -15
  106. data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
  107. data/lib/active_support/core_ext/object/json.rb +244 -0
  108. data/lib/active_support/core_ext/object/to_param.rb +3 -1
  109. data/lib/active_support/core_ext/object/to_query.rb +21 -8
  110. data/lib/active_support/core_ext/object/try.rb +106 -26
  111. data/lib/active_support/core_ext/object/with_options.rb +64 -5
  112. data/lib/active_support/core_ext/object.rb +14 -12
  113. data/lib/active_support/core_ext/pathname/existence.rb +21 -0
  114. data/lib/active_support/core_ext/pathname.rb +3 -0
  115. data/lib/active_support/core_ext/range/compare_range.rb +57 -0
  116. data/lib/active_support/core_ext/range/conversions.rb +37 -15
  117. data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
  118. data/lib/active_support/core_ext/range/each.rb +18 -17
  119. data/lib/active_support/core_ext/range/include_time_with_zone.rb +7 -0
  120. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  121. data/lib/active_support/core_ext/range.rb +7 -4
  122. data/lib/active_support/core_ext/regexp.rb +10 -1
  123. data/lib/active_support/core_ext/securerandom.rb +45 -0
  124. data/lib/active_support/core_ext/string/access.rb +42 -51
  125. data/lib/active_support/core_ext/string/behavior.rb +3 -1
  126. data/lib/active_support/core_ext/string/conversions.rb +18 -13
  127. data/lib/active_support/core_ext/string/exclude.rb +5 -3
  128. data/lib/active_support/core_ext/string/filters.rb +97 -7
  129. data/lib/active_support/core_ext/string/indent.rb +6 -4
  130. data/lib/active_support/core_ext/string/inflections.rb +106 -25
  131. data/lib/active_support/core_ext/string/inquiry.rb +4 -1
  132. data/lib/active_support/core_ext/string/multibyte.rb +18 -9
  133. data/lib/active_support/core_ext/string/output_safety.rb +227 -54
  134. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
  135. data/lib/active_support/core_ext/string/strip.rb +6 -5
  136. data/lib/active_support/core_ext/string/zones.rb +4 -1
  137. data/lib/active_support/core_ext/string.rb +15 -13
  138. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
  139. data/lib/active_support/core_ext/symbol.rb +3 -0
  140. data/lib/active_support/core_ext/time/acts_like.rb +3 -1
  141. data/lib/active_support/core_ext/time/calculations.rb +178 -116
  142. data/lib/active_support/core_ext/time/compatibility.rb +16 -0
  143. data/lib/active_support/core_ext/time/conversions.rb +37 -25
  144. data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
  145. data/lib/active_support/core_ext/time/zones.rb +44 -42
  146. data/lib/active_support/core_ext/time.rb +8 -5
  147. data/lib/active_support/core_ext/uri.rb +4 -25
  148. data/lib/active_support/core_ext.rb +4 -2
  149. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  150. data/lib/active_support/current_attributes.rb +226 -0
  151. data/lib/active_support/dependencies/autoload.rb +3 -1
  152. data/lib/active_support/dependencies/interlock.rb +49 -0
  153. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  154. data/lib/active_support/dependencies.rb +71 -696
  155. data/lib/active_support/deprecation/behaviors.rb +65 -16
  156. data/lib/active_support/deprecation/constant_accessor.rb +52 -0
  157. data/lib/active_support/deprecation/disallowed.rb +56 -0
  158. data/lib/active_support/deprecation/instance_delegator.rb +16 -2
  159. data/lib/active_support/deprecation/method_wrappers.rb +62 -21
  160. data/lib/active_support/deprecation/proxy_wrappers.rb +82 -31
  161. data/lib/active_support/deprecation/reporting.rb +81 -18
  162. data/lib/active_support/deprecation.rb +19 -11
  163. data/lib/active_support/descendants_tracker.rb +192 -34
  164. data/lib/active_support/digest.rb +22 -0
  165. data/lib/active_support/duration/iso8601_parser.rb +123 -0
  166. data/lib/active_support/duration/iso8601_serializer.rb +67 -0
  167. data/lib/active_support/duration.rb +437 -39
  168. data/lib/active_support/encrypted_configuration.rb +56 -0
  169. data/lib/active_support/encrypted_file.rb +117 -0
  170. data/lib/active_support/environment_inquirer.rb +20 -0
  171. data/lib/active_support/error_reporter.rb +117 -0
  172. data/lib/active_support/evented_file_update_checker.rb +170 -0
  173. data/lib/active_support/execution_context/test_helper.rb +13 -0
  174. data/lib/active_support/execution_context.rb +53 -0
  175. data/lib/active_support/execution_wrapper.rb +151 -0
  176. data/lib/active_support/executor/test_helper.rb +7 -0
  177. data/lib/active_support/executor.rb +8 -0
  178. data/lib/active_support/file_update_checker.rb +62 -37
  179. data/lib/active_support/fork_tracker.rb +71 -0
  180. data/lib/active_support/gem_version.rb +17 -0
  181. data/lib/active_support/gzip.rb +7 -5
  182. data/lib/active_support/hash_with_indifferent_access.rb +207 -54
  183. data/lib/active_support/html_safe_translation.rb +43 -0
  184. data/lib/active_support/i18n.rb +10 -6
  185. data/lib/active_support/i18n_railtie.rb +48 -19
  186. data/lib/active_support/inflections.rb +19 -12
  187. data/lib/active_support/inflector/inflections.rb +97 -37
  188. data/lib/active_support/inflector/methods.rb +192 -157
  189. data/lib/active_support/inflector/transliterate.rb +83 -33
  190. data/lib/active_support/inflector.rb +7 -5
  191. data/lib/active_support/isolated_execution_state.rb +64 -0
  192. data/lib/active_support/json/decoding.rb +37 -42
  193. data/lib/active_support/json/encoding.rb +93 -293
  194. data/lib/active_support/json.rb +4 -2
  195. data/lib/active_support/key_generator.rb +30 -47
  196. data/lib/active_support/lazy_load_hooks.rb +54 -21
  197. data/lib/active_support/locale/en.rb +33 -0
  198. data/lib/active_support/locale/en.yml +10 -4
  199. data/lib/active_support/log_subscriber/test_helper.rb +14 -12
  200. data/lib/active_support/log_subscriber.rb +61 -18
  201. data/lib/active_support/logger.rb +40 -4
  202. data/lib/active_support/logger_silence.rb +17 -20
  203. data/lib/active_support/logger_thread_safe_level.rb +69 -0
  204. data/lib/active_support/message_encryptor.rb +178 -55
  205. data/lib/active_support/message_verifier.rb +195 -26
  206. data/lib/active_support/messages/metadata.rb +80 -0
  207. data/lib/active_support/messages/rotation_configuration.rb +23 -0
  208. data/lib/active_support/messages/rotator.rb +57 -0
  209. data/lib/active_support/multibyte/chars.rb +45 -92
  210. data/lib/active_support/multibyte/unicode.rb +44 -377
  211. data/lib/active_support/multibyte.rb +5 -3
  212. data/lib/active_support/notifications/fanout.rb +177 -44
  213. data/lib/active_support/notifications/instrumenter.rb +117 -17
  214. data/lib/active_support/notifications.rb +106 -39
  215. data/lib/active_support/number_helper/number_converter.rb +181 -0
  216. data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
  217. data/lib/active_support/number_helper/number_to_delimited_converter.rb +30 -0
  218. data/lib/active_support/number_helper/number_to_human_converter.rb +69 -0
  219. data/lib/active_support/number_helper/number_to_human_size_converter.rb +60 -0
  220. data/lib/active_support/number_helper/number_to_percentage_converter.rb +16 -0
  221. data/lib/active_support/number_helper/number_to_phone_converter.rb +59 -0
  222. data/lib/active_support/number_helper/number_to_rounded_converter.rb +59 -0
  223. data/lib/active_support/number_helper/rounding_helper.rb +46 -0
  224. data/lib/active_support/number_helper.rb +152 -394
  225. data/lib/active_support/option_merger.rb +18 -5
  226. data/lib/active_support/ordered_hash.rb +8 -6
  227. data/lib/active_support/ordered_options.rb +43 -7
  228. data/lib/active_support/parameter_filter.rb +138 -0
  229. data/lib/active_support/per_thread_registry.rb +24 -11
  230. data/lib/active_support/proxy_object.rb +2 -0
  231. data/lib/active_support/rails.rb +10 -11
  232. data/lib/active_support/railtie.rb +118 -12
  233. data/lib/active_support/reloader.rb +130 -0
  234. data/lib/active_support/rescuable.rb +112 -57
  235. data/lib/active_support/ruby_features.rb +7 -0
  236. data/lib/active_support/secure_compare_rotator.rb +51 -0
  237. data/lib/active_support/security_utils.rb +38 -0
  238. data/lib/active_support/string_inquirer.rb +11 -4
  239. data/lib/active_support/subscriber.rb +109 -39
  240. data/lib/active_support/tagged_logging.rb +54 -17
  241. data/lib/active_support/test_case.rb +121 -37
  242. data/lib/active_support/testing/assertions.rb +177 -39
  243. data/lib/active_support/testing/autorun.rb +5 -3
  244. data/lib/active_support/testing/constant_lookup.rb +3 -6
  245. data/lib/active_support/testing/declarative.rb +10 -22
  246. data/lib/active_support/testing/deprecation.rb +65 -11
  247. data/lib/active_support/testing/file_fixtures.rb +38 -0
  248. data/lib/active_support/testing/isolation.rb +56 -87
  249. data/lib/active_support/testing/method_call_assertions.rb +70 -0
  250. data/lib/active_support/testing/parallelization/server.rb +82 -0
  251. data/lib/active_support/testing/parallelization/worker.rb +103 -0
  252. data/lib/active_support/testing/parallelization.rb +55 -0
  253. data/lib/active_support/testing/parallelize_executor.rb +76 -0
  254. data/lib/active_support/testing/setup_and_teardown.rb +30 -10
  255. data/lib/active_support/testing/stream.rb +41 -0
  256. data/lib/active_support/testing/tagged_logging.rb +6 -4
  257. data/lib/active_support/testing/time_helpers.rb +246 -0
  258. data/lib/active_support/time.rb +13 -13
  259. data/lib/active_support/time_with_zone.rb +315 -90
  260. data/lib/active_support/values/time_zone.rb +306 -135
  261. data/lib/active_support/version.rb +6 -7
  262. data/lib/active_support/xml_mini/jdom.rb +117 -115
  263. data/lib/active_support/xml_mini/libxml.rb +22 -21
  264. data/lib/active_support/xml_mini/libxmlsax.rb +17 -19
  265. data/lib/active_support/xml_mini/nokogiri.rb +19 -19
  266. data/lib/active_support/xml_mini/nokogirisax.rb +16 -17
  267. data/lib/active_support/xml_mini/rexml.rb +25 -17
  268. data/lib/active_support/xml_mini.rb +67 -56
  269. data/lib/active_support.rb +58 -3
  270. metadata +125 -66
  271. data/lib/active_support/basic_object.rb +0 -11
  272. data/lib/active_support/buffered_logger.rb +0 -21
  273. data/lib/active_support/concurrency/latch.rb +0 -27
  274. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
  275. data/lib/active_support/core_ext/array/uniq_by.rb +0 -19
  276. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -40
  277. data/lib/active_support/core_ext/date_time/zones.rb +0 -24
  278. data/lib/active_support/core_ext/hash/diff.rb +0 -14
  279. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  280. data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
  281. data/lib/active_support/core_ext/logger.rb +0 -67
  282. data/lib/active_support/core_ext/marshal.rb +0 -21
  283. data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
  284. data/lib/active_support/core_ext/module/reachable.rb +0 -8
  285. data/lib/active_support/core_ext/object/to_json.rb +0 -27
  286. data/lib/active_support/core_ext/proc.rb +0 -17
  287. data/lib/active_support/core_ext/range/include_range.rb +0 -23
  288. data/lib/active_support/core_ext/string/encoding.rb +0 -8
  289. data/lib/active_support/core_ext/struct.rb +0 -6
  290. data/lib/active_support/core_ext/thread.rb +0 -79
  291. data/lib/active_support/core_ext/time/marshal.rb +0 -30
  292. data/lib/active_support/file_watcher.rb +0 -36
  293. data/lib/active_support/json/variable.rb +0 -18
  294. data/lib/active_support/testing/pending.rb +0 -14
  295. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -0,0 +1,76 @@
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
+ end
13
+
14
+ def start
15
+ parallelize if should_parallelize?
16
+ show_execution_info
17
+
18
+ parallel_executor.start if parallelized?
19
+ end
20
+
21
+ def <<(work)
22
+ parallel_executor << work if parallelized?
23
+ end
24
+
25
+ def shutdown
26
+ parallel_executor.shutdown if parallelized?
27
+ end
28
+
29
+ private
30
+ def parallel_executor
31
+ @parallel_executor ||= build_parallel_executor
32
+ end
33
+
34
+ def build_parallel_executor
35
+ case parallelize_with
36
+ when :processes
37
+ Testing::Parallelization.new(size)
38
+ when :threads
39
+ ActiveSupport::TestCase.lock_threads = false if defined?(ActiveSupport::TestCase.lock_threads)
40
+ Minitest::Parallel::Executor.new(size)
41
+ else
42
+ raise ArgumentError, "#{parallelize_with} is not a supported parallelization executor."
43
+ end
44
+ end
45
+
46
+ def parallelize
47
+ @parallelized = true
48
+ Minitest::Test.parallelize_me!
49
+ end
50
+
51
+ def parallelized?
52
+ @parallelized if defined?(@parallelized)
53
+ end
54
+
55
+ def should_parallelize?
56
+ ENV["PARALLEL_WORKERS"] || tests_count > threshold
57
+ end
58
+
59
+ def tests_count
60
+ @tests_count ||= Minitest::Runnable.runnables.sum { |runnable| runnable.runnable_methods.size }
61
+ end
62
+
63
+ def show_execution_info
64
+ puts execution_info
65
+ end
66
+
67
+ def execution_info
68
+ if parallelized?
69
+ "Running #{tests_count} tests in parallel using #{parallel_executor.size} #{parallelize_with}"
70
+ else
71
+ "Running #{tests_count} tests in a single process (parallelization threshold is #{threshold})"
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -1,33 +1,53 @@
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
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
6
20
  module SetupAndTeardown
7
- extend ActiveSupport::Concern
8
-
9
- included do
10
- include ActiveSupport::Callbacks
11
- define_callbacks :setup, :teardown
21
+ def self.prepended(klass)
22
+ klass.include ActiveSupport::Callbacks
23
+ klass.define_callbacks :setup, :teardown
24
+ klass.extend ClassMethods
12
25
  end
13
26
 
14
27
  module ClassMethods
28
+ # Add a callback, which runs before <tt>TestCase#setup</tt>.
15
29
  def setup(*args, &block)
16
30
  set_callback(:setup, :before, *args, &block)
17
31
  end
18
32
 
33
+ # Add a callback, which runs after <tt>TestCase#teardown</tt>.
19
34
  def teardown(*args, &block)
20
35
  set_callback(:teardown, :after, *args, &block)
21
36
  end
22
37
  end
23
38
 
24
- def before_setup
39
+ def before_setup # :nodoc:
25
40
  super
26
41
  run_callbacks :setup
27
42
  end
28
43
 
29
- def after_teardown
30
- run_callbacks :teardown
44
+ def after_teardown # :nodoc:
45
+ begin
46
+ run_callbacks :teardown
47
+ rescue => e
48
+ self.failures << Minitest::UnexpectedError.new(e)
49
+ end
50
+
31
51
  super
32
52
  end
33
53
  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}")
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
@@ -1,14 +1,16 @@
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
4
6
  # make test.log easier to search and follow along with.
5
- module TaggedLogging #:nodoc:
7
+ module TaggedLogging # :nodoc:
6
8
  attr_writer :tagged_logger
7
9
 
8
10
  def before_setup
9
- if tagged_logger
10
- heading = "#{self.class}: #{__name__}"
11
- divider = '-' * heading.size
11
+ if tagged_logger && tagged_logger.info?
12
+ heading = "#{self.class}: #{name}"
13
+ divider = "-" * heading.size
12
14
  tagged_logger.info divider
13
15
  tagged_logger.info heading
14
16
  tagged_logger.info divider
@@ -0,0 +1,246 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/module/redefine_method"
4
+ require "active_support/core_ext/time/calculations"
5
+ require "concurrent/map"
6
+
7
+ module ActiveSupport
8
+ module Testing
9
+ # Manages stubs for TimeHelpers
10
+ class SimpleStubs # :nodoc:
11
+ Stub = Struct.new(:object, :method_name, :original_method)
12
+
13
+ def initialize
14
+ @stubs = Concurrent::Map.new { |h, k| h[k] = {} }
15
+ end
16
+
17
+ # Stubs object.method_name with the given block
18
+ # If the method is already stubbed, remove that stub
19
+ # so that removing this stub will restore the original implementation.
20
+ # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
21
+ # target = Time.zone.local(2004, 11, 24, 1, 4, 44)
22
+ # simple_stubs.stub_object(Time, :now) { at(target.to_i) }
23
+ # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
24
+ def stub_object(object, method_name, &block)
25
+ if stub = stubbing(object, method_name)
26
+ unstub_object(stub)
27
+ end
28
+
29
+ new_name = "__simple_stub__#{method_name}"
30
+
31
+ @stubs[object.object_id][method_name] = Stub.new(object, method_name, new_name)
32
+
33
+ object.singleton_class.alias_method new_name, method_name
34
+ object.define_singleton_method(method_name, &block)
35
+ end
36
+
37
+ # Remove all object-method stubs held by this instance
38
+ def unstub_all!
39
+ @stubs.each_value do |object_stubs|
40
+ object_stubs.each_value do |stub|
41
+ unstub_object(stub)
42
+ end
43
+ end
44
+ @stubs.clear
45
+ end
46
+
47
+ # Returns the Stub for object#method_name
48
+ # (nil if it is not stubbed)
49
+ def stubbing(object, method_name)
50
+ @stubs[object.object_id][method_name]
51
+ end
52
+
53
+ # Returns true if any stubs are set, false if there are none
54
+ def stubbed?
55
+ !@stubs.empty?
56
+ end
57
+
58
+ private
59
+ # Restores the original object.method described by the Stub
60
+ def unstub_object(stub)
61
+ singleton_class = stub.object.singleton_class
62
+ singleton_class.silence_redefinition_of_method stub.method_name
63
+ singleton_class.alias_method stub.method_name, stub.original_method
64
+ singleton_class.undef_method stub.original_method
65
+ end
66
+ end
67
+
68
+ # Contains helpers that help you test passage of time.
69
+ module TimeHelpers
70
+ def after_teardown
71
+ travel_back
72
+ super
73
+ end
74
+
75
+ # Changes current time to the time in the future or in the past by a given time difference by
76
+ # stubbing +Time.now+, +Date.today+, and +DateTime.now+. The stubs are automatically removed
77
+ # at the end of the test.
78
+ #
79
+ # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
80
+ # travel 1.day
81
+ # Time.current # => Sun, 10 Nov 2013 15:34:49 EST -05:00
82
+ # Date.current # => Sun, 10 Nov 2013
83
+ # DateTime.current # => Sun, 10 Nov 2013 15:34:49 -0500
84
+ #
85
+ # This method also accepts a block, which will return the current time back to its original
86
+ # state at the end of the block:
87
+ #
88
+ # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
89
+ # travel 1.day do
90
+ # User.create.created_at # => Sun, 10 Nov 2013 15:34:49 EST -05:00
91
+ # end
92
+ # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
93
+ def travel(duration, &block)
94
+ travel_to Time.now + duration, &block
95
+ end
96
+
97
+ # Changes current time to the given time by stubbing +Time.now+,
98
+ # +Date.today+, and +DateTime.now+ to return the time or date passed into this method.
99
+ # The stubs are automatically removed at the end of the test.
100
+ #
101
+ # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
102
+ # travel_to Time.zone.local(2004, 11, 24, 1, 4, 44)
103
+ # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
104
+ # Date.current # => Wed, 24 Nov 2004
105
+ # DateTime.current # => Wed, 24 Nov 2004 01:04:44 -0500
106
+ #
107
+ # Dates are taken as their timestamp at the beginning of the day in the
108
+ # application time zone. <tt>Time.current</tt> returns said timestamp,
109
+ # and <tt>Time.now</tt> its equivalent in the system time zone. Similarly,
110
+ # <tt>Date.current</tt> returns a date equal to the argument, and
111
+ # <tt>Date.today</tt> the date according to <tt>Time.now</tt>, which may
112
+ # be different. (Note that you rarely want to deal with <tt>Time.now</tt>,
113
+ # or <tt>Date.today</tt>, in order to honor the application time zone
114
+ # please always use <tt>Time.current</tt> and <tt>Date.current</tt>.)
115
+ #
116
+ # Note that the usec for the time passed will be set to 0 to prevent rounding
117
+ # errors with external services, like MySQL (which will round instead of floor,
118
+ # leading to off-by-one-second errors).
119
+ #
120
+ # This method also accepts a block, which will return the current time back to its original
121
+ # state at the end of the block:
122
+ #
123
+ # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
124
+ # travel_to Time.zone.local(2004, 11, 24, 1, 4, 44) do
125
+ # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
126
+ # end
127
+ # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
128
+ def travel_to(date_or_time)
129
+ if block_given? && in_block
130
+ travel_to_nested_block_call = <<~MSG
131
+
132
+ Calling `travel_to` with a block, when we have previously already made a call to `travel_to`, can lead to confusing time stubbing.
133
+
134
+ Instead of:
135
+
136
+ travel_to 2.days.from_now do
137
+ # 2 days from today
138
+ travel_to 3.days.from_now do
139
+ # 5 days from today
140
+ end
141
+ end
142
+
143
+ preferred way to achieve above is:
144
+
145
+ travel 2.days do
146
+ # 2 days from today
147
+ end
148
+
149
+ travel 5.days do
150
+ # 5 days from today
151
+ end
152
+
153
+ MSG
154
+ raise travel_to_nested_block_call
155
+ end
156
+
157
+ if date_or_time.is_a?(Date) && !date_or_time.is_a?(DateTime)
158
+ now = date_or_time.midnight.to_time
159
+ elsif date_or_time.is_a?(String)
160
+ now = Time.zone.parse(date_or_time)
161
+ else
162
+ now = date_or_time.to_time.change(usec: 0)
163
+ end
164
+
165
+ stubbed_time = Time.now if simple_stubs.stubbing(Time, :now)
166
+ simple_stubs.stub_object(Time, :now) { at(now.to_i) }
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)) }
169
+
170
+ if block_given?
171
+ begin
172
+ self.in_block = true
173
+ yield
174
+ ensure
175
+ if stubbed_time
176
+ travel_to stubbed_time
177
+ else
178
+ travel_back
179
+ end
180
+ self.in_block = false
181
+ end
182
+ end
183
+ end
184
+
185
+ # Returns the current time back to its original state, by removing the stubs added by
186
+ # +travel+, +travel_to+, and +freeze_time+.
187
+ #
188
+ # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
189
+ #
190
+ # travel_to Time.zone.local(2004, 11, 24, 1, 4, 44)
191
+ # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
192
+ #
193
+ # travel_back
194
+ # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
195
+ #
196
+ # This method also accepts a block, which brings the stubs back at the end of the block:
197
+ #
198
+ # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
199
+ #
200
+ # travel_to Time.zone.local(2004, 11, 24, 1, 4, 44)
201
+ # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
202
+ #
203
+ # travel_back do
204
+ # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
205
+ # end
206
+ #
207
+ # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
208
+ def travel_back
209
+ stubbed_time = Time.current if block_given? && simple_stubs.stubbed?
210
+
211
+ simple_stubs.unstub_all!
212
+ yield if block_given?
213
+ ensure
214
+ travel_to stubbed_time if stubbed_time
215
+ end
216
+ alias_method :unfreeze_time, :travel_back
217
+
218
+ # Calls +travel_to+ with +Time.now+.
219
+ #
220
+ # Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00
221
+ # freeze_time
222
+ # sleep(1)
223
+ # Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00
224
+ #
225
+ # This method also accepts a block, which will return the current time back to its original
226
+ # state at the end of the block:
227
+ #
228
+ # Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00
229
+ # freeze_time do
230
+ # sleep(1)
231
+ # User.create.created_at # => Sun, 09 Jul 2017 15:34:49 EST -05:00
232
+ # end
233
+ # Time.current # => Sun, 09 Jul 2017 15:34:50 EST -05:00
234
+ def freeze_time(&block)
235
+ travel_to Time.now, &block
236
+ end
237
+
238
+ private
239
+ def simple_stubs
240
+ @simple_stubs ||= SimpleStubs.new
241
+ end
242
+
243
+ attr_accessor :in_block
244
+ end
245
+ end
246
+ end
@@ -1,20 +1,20 @@
1
- require 'active_support'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module ActiveSupport
4
- autoload :Duration, 'active_support/duration'
5
- autoload :TimeWithZone, 'active_support/time_with_zone'
6
- autoload :TimeZone, 'active_support/values/time_zone'
4
+ autoload :Duration, "active_support/duration"
5
+ autoload :TimeWithZone, "active_support/time_with_zone"
6
+ autoload :TimeZone, "active_support/values/time_zone"
7
7
  end
8
8
 
9
- require 'date'
10
- require 'time'
9
+ require "date"
10
+ require "time"
11
11
 
12
- require 'active_support/core_ext/time'
13
- require 'active_support/core_ext/date'
14
- require 'active_support/core_ext/date_time'
12
+ require "active_support/core_ext/time"
13
+ require "active_support/core_ext/date"
14
+ require "active_support/core_ext/date_time"
15
15
 
16
- require 'active_support/core_ext/integer/time'
17
- require 'active_support/core_ext/numeric/time'
16
+ require "active_support/core_ext/integer/time"
17
+ require "active_support/core_ext/numeric/time"
18
18
 
19
- require 'active_support/core_ext/string/conversions'
20
- require 'active_support/core_ext/string/zones'
19
+ require "active_support/core_ext/string/conversions"
20
+ require "active_support/core_ext/string/zones"