activesupport 4.2.11.1 → 6.1.7.3

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 (272) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +464 -391
  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 +50 -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 +61 -55
  12. data/lib/active_support/cache/mem_cache_store.rb +115 -100
  13. data/lib/active_support/cache/memory_store.rb +81 -58
  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 +90 -42
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
  18. data/lib/active_support/cache.rb +386 -225
  19. data/lib/active_support/callbacks.rb +661 -594
  20. data/lib/active_support/concern.rb +80 -7
  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 +16 -17
  24. data/lib/active_support/configuration_file.rb +51 -0
  25. data/lib/active_support/core_ext/array/access.rb +41 -1
  26. data/lib/active_support/core_ext/array/conversions.rb +24 -20
  27. data/lib/active_support/core_ext/array/extract.rb +21 -0
  28. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  29. data/lib/active_support/core_ext/array/grouping.rb +11 -18
  30. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  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 +5 -3
  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 +52 -48
  37. data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
  38. data/lib/active_support/core_ext/class/subclasses.rb +18 -25
  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 +27 -24
  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 +167 -65
  47. data/lib/active_support/core_ext/date_and_time/compatibility.rb +19 -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 +8 -5
  56. data/lib/active_support/core_ext/digest.rb +3 -0
  57. data/lib/active_support/core_ext/enumerable.rb +186 -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/conversions.rb +62 -41
  61. data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
  62. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  63. data/lib/active_support/core_ext/hash/except.rb +13 -10
  64. data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
  65. data/lib/active_support/core_ext/hash/keys.rb +20 -43
  66. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  67. data/lib/active_support/core_ext/hash/slice.rb +8 -29
  68. data/lib/active_support/core_ext/hash.rb +10 -9
  69. data/lib/active_support/core_ext/integer/inflections.rb +3 -1
  70. data/lib/active_support/core_ext/integer/multiple.rb +3 -1
  71. data/lib/active_support/core_ext/integer/time.rb +11 -18
  72. data/lib/active_support/core_ext/integer.rb +5 -3
  73. data/lib/active_support/core_ext/kernel/concern.rb +5 -1
  74. data/lib/active_support/core_ext/kernel/reporting.rb +4 -84
  75. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  76. data/lib/active_support/core_ext/kernel.rb +5 -5
  77. data/lib/active_support/core_ext/load_error.rb +3 -22
  78. data/lib/active_support/core_ext/marshal.rb +10 -8
  79. data/lib/active_support/core_ext/module/aliasing.rb +6 -44
  80. data/lib/active_support/core_ext/module/anonymous.rb +12 -1
  81. data/lib/active_support/core_ext/module/attr_internal.rb +8 -9
  82. data/lib/active_support/core_ext/module/attribute_accessors.rb +63 -69
  83. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +148 -0
  84. data/lib/active_support/core_ext/module/concerning.rb +19 -14
  85. data/lib/active_support/core_ext/module/delegation.rb +164 -51
  86. data/lib/active_support/core_ext/module/deprecation.rb +4 -2
  87. data/lib/active_support/core_ext/module/introspection.rb +23 -22
  88. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  89. data/lib/active_support/core_ext/module/remove_method.rb +8 -3
  90. data/lib/active_support/core_ext/module.rb +13 -11
  91. data/lib/active_support/core_ext/name_error.rb +51 -4
  92. data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
  93. data/lib/active_support/core_ext/numeric/conversions.rb +133 -136
  94. data/lib/active_support/core_ext/numeric/time.rb +35 -23
  95. data/lib/active_support/core_ext/numeric.rb +5 -3
  96. data/lib/active_support/core_ext/object/acts_like.rb +12 -1
  97. data/lib/active_support/core_ext/object/blank.rb +27 -3
  98. data/lib/active_support/core_ext/object/conversions.rb +6 -4
  99. data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
  100. data/lib/active_support/core_ext/object/duplicable.rb +13 -93
  101. data/lib/active_support/core_ext/object/inclusion.rb +5 -3
  102. data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
  103. data/lib/active_support/core_ext/object/json.rb +63 -21
  104. data/lib/active_support/core_ext/object/to_param.rb +3 -1
  105. data/lib/active_support/core_ext/object/to_query.rb +10 -5
  106. data/lib/active_support/core_ext/object/try.rb +81 -23
  107. data/lib/active_support/core_ext/object/with_options.rb +16 -3
  108. data/lib/active_support/core_ext/object.rb +14 -13
  109. data/lib/active_support/core_ext/range/compare_range.rb +82 -0
  110. data/lib/active_support/core_ext/range/conversions.rb +37 -15
  111. data/lib/active_support/core_ext/range/each.rb +18 -17
  112. data/lib/active_support/core_ext/range/include_time_with_zone.rb +28 -0
  113. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  114. data/lib/active_support/core_ext/range.rb +7 -4
  115. data/lib/active_support/core_ext/regexp.rb +10 -1
  116. data/lib/active_support/core_ext/securerandom.rb +45 -0
  117. data/lib/active_support/core_ext/string/access.rb +9 -18
  118. data/lib/active_support/core_ext/string/behavior.rb +3 -1
  119. data/lib/active_support/core_ext/string/conversions.rb +8 -4
  120. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  121. data/lib/active_support/core_ext/string/filters.rb +48 -6
  122. data/lib/active_support/core_ext/string/indent.rb +6 -4
  123. data/lib/active_support/core_ext/string/inflections.rb +102 -26
  124. data/lib/active_support/core_ext/string/inquiry.rb +4 -1
  125. data/lib/active_support/core_ext/string/multibyte.rb +18 -9
  126. data/lib/active_support/core_ext/string/output_safety.rb +125 -40
  127. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
  128. data/lib/active_support/core_ext/string/strip.rb +6 -5
  129. data/lib/active_support/core_ext/string/zones.rb +4 -2
  130. data/lib/active_support/core_ext/string.rb +15 -13
  131. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +14 -0
  132. data/lib/active_support/core_ext/symbol.rb +3 -0
  133. data/lib/active_support/core_ext/time/acts_like.rb +3 -1
  134. data/lib/active_support/core_ext/time/calculations.rb +137 -53
  135. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  136. data/lib/active_support/core_ext/time/conversions.rb +22 -13
  137. data/lib/active_support/core_ext/time/zones.rb +41 -7
  138. data/lib/active_support/core_ext/time.rb +7 -6
  139. data/lib/active_support/core_ext/uri.rb +11 -8
  140. data/lib/active_support/core_ext.rb +3 -1
  141. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  142. data/lib/active_support/current_attributes.rb +210 -0
  143. data/lib/active_support/dependencies/autoload.rb +2 -0
  144. data/lib/active_support/dependencies/interlock.rb +57 -0
  145. data/lib/active_support/dependencies/zeitwerk_integration.rb +120 -0
  146. data/lib/active_support/dependencies.rb +241 -175
  147. data/lib/active_support/deprecation/behaviors.rb +58 -12
  148. data/lib/active_support/deprecation/constant_accessor.rb +52 -0
  149. data/lib/active_support/deprecation/disallowed.rb +56 -0
  150. data/lib/active_support/deprecation/instance_delegator.rb +16 -2
  151. data/lib/active_support/deprecation/method_wrappers.rb +62 -21
  152. data/lib/active_support/deprecation/proxy_wrappers.rb +81 -30
  153. data/lib/active_support/deprecation/reporting.rb +81 -18
  154. data/lib/active_support/deprecation.rb +17 -9
  155. data/lib/active_support/descendants_tracker.rb +61 -9
  156. data/lib/active_support/digest.rb +22 -0
  157. data/lib/active_support/duration/iso8601_parser.rb +123 -0
  158. data/lib/active_support/duration/iso8601_serializer.rb +59 -0
  159. data/lib/active_support/duration.rb +364 -39
  160. data/lib/active_support/encrypted_configuration.rb +45 -0
  161. data/lib/active_support/encrypted_file.rb +117 -0
  162. data/lib/active_support/environment_inquirer.rb +20 -0
  163. data/lib/active_support/evented_file_update_checker.rb +170 -0
  164. data/lib/active_support/execution_wrapper.rb +132 -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/fork_tracker.rb +64 -0
  168. data/lib/active_support/gem_version.rb +7 -5
  169. data/lib/active_support/gzip.rb +7 -5
  170. data/lib/active_support/hash_with_indifferent_access.rb +171 -48
  171. data/lib/active_support/i18n.rb +9 -6
  172. data/lib/active_support/i18n_railtie.rb +47 -16
  173. data/lib/active_support/inflections.rb +13 -11
  174. data/lib/active_support/inflector/inflections.rb +58 -14
  175. data/lib/active_support/inflector/methods.rb +186 -169
  176. data/lib/active_support/inflector/transliterate.rb +83 -33
  177. data/lib/active_support/inflector.rb +7 -5
  178. data/lib/active_support/json/decoding.rb +32 -30
  179. data/lib/active_support/json/encoding.rb +22 -61
  180. data/lib/active_support/json.rb +4 -2
  181. data/lib/active_support/key_generator.rb +11 -43
  182. data/lib/active_support/lazy_load_hooks.rb +53 -20
  183. data/lib/active_support/locale/en.rb +33 -0
  184. data/lib/active_support/locale/en.yml +9 -3
  185. data/lib/active_support/log_subscriber/test_helper.rb +14 -12
  186. data/lib/active_support/log_subscriber.rb +52 -19
  187. data/lib/active_support/logger.rb +10 -24
  188. data/lib/active_support/logger_silence.rb +14 -20
  189. data/lib/active_support/logger_thread_safe_level.rb +56 -10
  190. data/lib/active_support/message_encryptor.rb +167 -57
  191. data/lib/active_support/message_verifier.rb +151 -18
  192. data/lib/active_support/messages/metadata.rb +80 -0
  193. data/lib/active_support/messages/rotation_configuration.rb +23 -0
  194. data/lib/active_support/messages/rotator.rb +57 -0
  195. data/lib/active_support/multibyte/chars.rb +35 -80
  196. data/lib/active_support/multibyte/unicode.rb +22 -330
  197. data/lib/active_support/multibyte.rb +4 -2
  198. data/lib/active_support/notifications/fanout.rb +125 -23
  199. data/lib/active_support/notifications/instrumenter.rb +98 -16
  200. data/lib/active_support/notifications.rb +82 -14
  201. data/lib/active_support/number_helper/number_converter.rb +17 -16
  202. data/lib/active_support/number_helper/number_to_currency_converter.rb +9 -14
  203. data/lib/active_support/number_helper/number_to_delimited_converter.rb +11 -4
  204. data/lib/active_support/number_helper/number_to_human_converter.rb +14 -11
  205. data/lib/active_support/number_helper/number_to_human_size_converter.rb +12 -10
  206. data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
  207. data/lib/active_support/number_helper/number_to_phone_converter.rb +15 -5
  208. data/lib/active_support/number_helper/number_to_rounded_converter.rb +29 -57
  209. data/lib/active_support/number_helper/rounding_helper.rb +50 -0
  210. data/lib/active_support/number_helper.rb +123 -71
  211. data/lib/active_support/option_merger.rb +25 -4
  212. data/lib/active_support/ordered_hash.rb +7 -5
  213. data/lib/active_support/ordered_options.rb +35 -7
  214. data/lib/active_support/parameter_filter.rb +133 -0
  215. data/lib/active_support/per_thread_registry.rb +10 -4
  216. data/lib/active_support/proxy_object.rb +2 -0
  217. data/lib/active_support/rails.rb +10 -11
  218. data/lib/active_support/railtie.rb +66 -10
  219. data/lib/active_support/reloader.rb +130 -0
  220. data/lib/active_support/rescuable.rb +112 -57
  221. data/lib/active_support/secure_compare_rotator.rb +51 -0
  222. data/lib/active_support/security_utils.rb +26 -15
  223. data/lib/active_support/string_inquirer.rb +13 -4
  224. data/lib/active_support/subscriber.rb +80 -31
  225. data/lib/active_support/tagged_logging.rb +54 -17
  226. data/lib/active_support/test_case.rb +107 -44
  227. data/lib/active_support/testing/assertions.rb +158 -20
  228. data/lib/active_support/testing/autorun.rb +4 -2
  229. data/lib/active_support/testing/constant_lookup.rb +2 -1
  230. data/lib/active_support/testing/declarative.rb +3 -1
  231. data/lib/active_support/testing/deprecation.rb +13 -10
  232. data/lib/active_support/testing/file_fixtures.rb +38 -0
  233. data/lib/active_support/testing/isolation.rb +35 -26
  234. data/lib/active_support/testing/method_call_assertions.rb +70 -0
  235. data/lib/active_support/testing/parallelization/server.rb +78 -0
  236. data/lib/active_support/testing/parallelization/worker.rb +100 -0
  237. data/lib/active_support/testing/parallelization.rb +51 -0
  238. data/lib/active_support/testing/setup_and_teardown.rb +13 -8
  239. data/lib/active_support/testing/stream.rb +43 -0
  240. data/lib/active_support/testing/tagged_logging.rb +3 -1
  241. data/lib/active_support/testing/time_helpers.rb +121 -20
  242. data/lib/active_support/time.rb +14 -12
  243. data/lib/active_support/time_with_zone.rb +215 -51
  244. data/lib/active_support/values/time_zone.rb +223 -71
  245. data/lib/active_support/version.rb +3 -1
  246. data/lib/active_support/xml_mini/jdom.rb +116 -115
  247. data/lib/active_support/xml_mini/libxml.rb +16 -13
  248. data/lib/active_support/xml_mini/libxmlsax.rb +15 -14
  249. data/lib/active_support/xml_mini/nokogiri.rb +14 -12
  250. data/lib/active_support/xml_mini/nokogirisax.rb +14 -13
  251. data/lib/active_support/xml_mini/rexml.rb +18 -9
  252. data/lib/active_support/xml_mini.rb +38 -46
  253. data/lib/active_support.rb +25 -11
  254. metadata +100 -43
  255. data/lib/active_support/concurrency/latch.rb +0 -27
  256. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
  257. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
  258. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
  259. data/lib/active_support/core_ext/date_time/zones.rb +0 -6
  260. data/lib/active_support/core_ext/hash/compact.rb +0 -24
  261. data/lib/active_support/core_ext/hash/transform_values.rb +0 -23
  262. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  263. data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
  264. data/lib/active_support/core_ext/module/method_transplanting.rb +0 -13
  265. data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
  266. data/lib/active_support/core_ext/module/reachable.rb +0 -8
  267. data/lib/active_support/core_ext/object/itself.rb +0 -15
  268. data/lib/active_support/core_ext/range/include_range.rb +0 -23
  269. data/lib/active_support/core_ext/struct.rb +0 -6
  270. data/lib/active_support/core_ext/thread.rb +0 -86
  271. data/lib/active_support/core_ext/time/marshal.rb +0 -30
  272. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,15 +1,18 @@
1
- gem 'minitest' # make sure we get the gem, not stdlib
2
- require 'minitest'
3
- require 'active_support/testing/tagged_logging'
4
- require 'active_support/testing/setup_and_teardown'
5
- require 'active_support/testing/assertions'
6
- require 'active_support/testing/deprecation'
7
- require 'active_support/testing/declarative'
8
- require 'active_support/testing/isolation'
9
- require 'active_support/testing/constant_lookup'
10
- require 'active_support/testing/time_helpers'
11
- require 'active_support/core_ext/kernel/reporting'
12
- require 'active_support/deprecation'
1
+ # frozen_string_literal: true
2
+
3
+ gem "minitest" # make sure we get the gem, not stdlib
4
+ require "minitest"
5
+ require "active_support/testing/tagged_logging"
6
+ require "active_support/testing/setup_and_teardown"
7
+ require "active_support/testing/assertions"
8
+ require "active_support/testing/deprecation"
9
+ require "active_support/testing/declarative"
10
+ require "active_support/testing/isolation"
11
+ require "active_support/testing/constant_lookup"
12
+ require "active_support/testing/time_helpers"
13
+ require "active_support/testing/file_fixtures"
14
+ require "active_support/testing/parallelization"
15
+ require "concurrent/utility/processor_counter"
13
16
 
14
17
  module ActiveSupport
15
18
  class TestCase < ::Minitest::Test
@@ -31,45 +34,112 @@ module ActiveSupport
31
34
 
32
35
  # Returns the order in which test cases are run.
33
36
  #
34
- # ActiveSupport::TestCase.test_order # => :sorted
37
+ # ActiveSupport::TestCase.test_order # => :random
35
38
  #
36
39
  # Possible values are +:random+, +:parallel+, +:alpha+, +:sorted+.
37
- # Defaults to +:sorted+.
40
+ # Defaults to +:random+.
38
41
  def test_order
39
- test_order = ActiveSupport.test_order
40
-
41
- if test_order.nil?
42
- ActiveSupport::Deprecation.warn "You did not specify a value for the " \
43
- "configuration option `active_support.test_order`. In Rails 5, " \
44
- "the default value of this option will change from `:sorted` to " \
45
- "`:random`.\n" \
46
- "To disable this warning and keep the current behavior, you can add " \
47
- "the following line to your `config/environments/test.rb`:\n" \
48
- "\n" \
49
- " Rails.application.configure do\n" \
50
- " config.active_support.test_order = :sorted\n" \
51
- " end\n" \
52
- "\n" \
53
- "Alternatively, you can opt into the future behavior by setting this " \
54
- "option to `:random`."
55
-
56
- test_order = :sorted
57
- self.test_order = test_order
42
+ ActiveSupport.test_order ||= :random
43
+ end
44
+
45
+ # Parallelizes the test suite.
46
+ #
47
+ # Takes a +workers+ argument that controls how many times the process
48
+ # is forked. For each process a new database will be created suffixed
49
+ # with the worker number.
50
+ #
51
+ # test-database-0
52
+ # test-database-1
53
+ #
54
+ # If <tt>ENV["PARALLEL_WORKERS"]</tt> is set the workers argument will be ignored
55
+ # and the environment variable will be used instead. This is useful for CI
56
+ # environments, or other environments where you may need more workers than
57
+ # you do for local testing.
58
+ #
59
+ # If the number of workers is set to +1+ or fewer, the tests will not be
60
+ # parallelized.
61
+ #
62
+ # If +workers+ is set to +:number_of_processors+, the number of workers will be
63
+ # set to the actual core count on the machine you are on.
64
+ #
65
+ # The default parallelization method is to fork processes. If you'd like to
66
+ # use threads instead you can pass <tt>with: :threads</tt> to the +parallelize+
67
+ # method. Note the threaded parallelization does not create multiple
68
+ # database and will not work with system tests at this time.
69
+ #
70
+ # parallelize(workers: :number_of_processors, with: :threads)
71
+ #
72
+ # The threaded parallelization uses minitest's parallel executor directly.
73
+ # The processes parallelization uses a Ruby DRb server.
74
+ def parallelize(workers: :number_of_processors, with: :processes)
75
+ workers = Concurrent.physical_processor_count if workers == :number_of_processors
76
+ workers = ENV["PARALLEL_WORKERS"].to_i if ENV["PARALLEL_WORKERS"]
77
+
78
+ return if workers <= 1
79
+
80
+ executor = case with
81
+ when :processes
82
+ Testing::Parallelization.new(workers)
83
+ when :threads
84
+ Minitest::Parallel::Executor.new(workers)
85
+ else
86
+ raise ArgumentError, "#{with} is not a supported parallelization executor."
58
87
  end
59
88
 
60
- test_order
89
+ self.lock_threads = false if defined?(self.lock_threads) && with == :threads
90
+
91
+ Minitest.parallel_executor = executor
92
+
93
+ parallelize_me!
94
+ end
95
+
96
+ # Set up hook for parallel testing. This can be used if you have multiple
97
+ # databases or any behavior that needs to be run after the process is forked
98
+ # but before the tests run.
99
+ #
100
+ # Note: this feature is not available with the threaded parallelization.
101
+ #
102
+ # In your +test_helper.rb+ add the following:
103
+ #
104
+ # class ActiveSupport::TestCase
105
+ # parallelize_setup do
106
+ # # create databases
107
+ # end
108
+ # end
109
+ def parallelize_setup(&block)
110
+ ActiveSupport::Testing::Parallelization.after_fork_hook do |worker|
111
+ yield worker
112
+ end
61
113
  end
62
114
 
63
- alias :my_tests_are_order_dependent! :i_suck_and_my_tests_are_order_dependent!
115
+ # Clean up hook for parallel testing. This can be used to drop databases
116
+ # if your app uses multiple write/read databases or other clean up before
117
+ # the tests finish. This runs before the forked process is closed.
118
+ #
119
+ # Note: this feature is not available with the threaded parallelization.
120
+ #
121
+ # In your +test_helper.rb+ add the following:
122
+ #
123
+ # class ActiveSupport::TestCase
124
+ # parallelize_teardown do
125
+ # # drop databases
126
+ # end
127
+ # end
128
+ def parallelize_teardown(&block)
129
+ ActiveSupport::Testing::Parallelization.run_cleanup_hook do |worker|
130
+ yield worker
131
+ end
132
+ end
64
133
  end
65
134
 
66
135
  alias_method :method_name, :name
67
136
 
68
137
  include ActiveSupport::Testing::TaggedLogging
69
- include ActiveSupport::Testing::SetupAndTeardown
138
+ prepend ActiveSupport::Testing::SetupAndTeardown
70
139
  include ActiveSupport::Testing::Assertions
71
140
  include ActiveSupport::Testing::Deprecation
72
141
  include ActiveSupport::Testing::TimeHelpers
142
+ include ActiveSupport::Testing::FileFixtures
73
143
  extend ActiveSupport::Testing::Declarative
74
144
 
75
145
  # test/unit backwards compatibility methods
@@ -88,13 +158,6 @@ module ActiveSupport
88
158
  alias :assert_not_respond_to :refute_respond_to
89
159
  alias :assert_not_same :refute_same
90
160
 
91
- # Fails if the block raises an exception.
92
- #
93
- # assert_nothing_raised do
94
- # ...
95
- # end
96
- def assert_nothing_raised(*args)
97
- yield
98
- end
161
+ ActiveSupport.run_load_hooks(:active_support_test_case, self)
99
162
  end
100
163
  end
@@ -1,9 +1,13 @@
1
- require 'active_support/core_ext/object/blank'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/enumerable"
2
4
 
3
5
  module ActiveSupport
4
6
  module Testing
5
7
  module Assertions
6
- # Assert that an expression is not truthy. Passes if <tt>object</tt> is
8
+ UNTRACKED = Object.new # :nodoc:
9
+
10
+ # Asserts that an expression is not truthy. Passes if <tt>object</tt> is
7
11
  # +nil+ or +false+. "Truthy" means "considered true in a conditional"
8
12
  # like <tt>if foo</tt>.
9
13
  #
@@ -19,79 +23,213 @@ module ActiveSupport
19
23
  assert !object, message
20
24
  end
21
25
 
26
+ # Assertion that the block should not raise an exception.
27
+ #
28
+ # Passes if evaluated code in the yielded block raises no exception.
29
+ #
30
+ # assert_nothing_raised do
31
+ # perform_service(param: 'no_exception')
32
+ # end
33
+ def assert_nothing_raised
34
+ yield
35
+ rescue => error
36
+ raise Minitest::UnexpectedError.new(error)
37
+ end
38
+
22
39
  # Test numeric difference between the return value of an expression as a
23
40
  # result of what is evaluated in the yielded block.
24
41
  #
25
42
  # assert_difference 'Article.count' do
26
- # post :create, article: {...}
43
+ # post :create, params: { article: {...} }
27
44
  # end
28
45
  #
29
46
  # An arbitrary expression is passed in and evaluated.
30
47
  #
31
- # assert_difference 'assigns(:article).comments(:reload).size' do
32
- # post :create, comment: {...}
48
+ # assert_difference 'Article.last.comments(:reload).size' do
49
+ # post :create, params: { comment: {...} }
33
50
  # end
34
51
  #
35
52
  # An arbitrary positive or negative difference can be specified.
36
53
  # The default is <tt>1</tt>.
37
54
  #
38
55
  # assert_difference 'Article.count', -1 do
39
- # post :delete, id: ...
56
+ # post :delete, params: { id: ... }
40
57
  # end
41
58
  #
42
59
  # An array of expressions can also be passed in and evaluated.
43
60
  #
44
61
  # assert_difference [ 'Article.count', 'Post.count' ], 2 do
45
- # post :create, article: {...}
62
+ # post :create, params: { article: {...} }
63
+ # end
64
+ #
65
+ # A hash of expressions/numeric differences can also be passed in and evaluated.
66
+ #
67
+ # assert_difference ->{ Article.count } => 1, ->{ Notification.count } => 2 do
68
+ # post :create, params: { article: {...} }
46
69
  # end
47
70
  #
48
71
  # A lambda or a list of lambdas can be passed in and evaluated:
49
72
  #
50
73
  # assert_difference ->{ Article.count }, 2 do
51
- # post :create, article: {...}
74
+ # post :create, params: { article: {...} }
52
75
  # end
53
76
  #
54
77
  # assert_difference [->{ Article.count }, ->{ Post.count }], 2 do
55
- # post :create, article: {...}
78
+ # post :create, params: { article: {...} }
56
79
  # end
57
80
  #
58
81
  # An error message can be specified.
59
82
  #
60
83
  # assert_difference 'Article.count', -1, 'An Article should be destroyed' do
61
- # post :delete, id: ...
84
+ # post :delete, params: { id: ... }
62
85
  # end
63
- def assert_difference(expression, difference = 1, message = nil, &block)
64
- expressions = Array(expression)
86
+ def assert_difference(expression, *args, &block)
87
+ expressions =
88
+ if expression.is_a?(Hash)
89
+ message = args[0]
90
+ expression
91
+ else
92
+ difference = args[0] || 1
93
+ message = args[1]
94
+ Array(expression).index_with(difference)
95
+ end
65
96
 
66
- exps = expressions.map { |e|
97
+ exps = expressions.keys.map { |e|
67
98
  e.respond_to?(:call) ? e : lambda { eval(e, block.binding) }
68
99
  }
69
- before = exps.map { |e| e.call }
100
+ before = exps.map(&:call)
70
101
 
71
- yield
102
+ retval = assert_nothing_raised(&block)
72
103
 
73
- expressions.zip(exps).each_with_index do |(code, e), i|
74
- error = "#{code.inspect} didn't change by #{difference}"
104
+ expressions.zip(exps, before) do |(code, diff), exp, before_value|
105
+ error = "#{code.inspect} didn't change by #{diff}"
75
106
  error = "#{message}.\n#{error}" if message
76
- assert_equal(before[i] + difference, e.call, error)
107
+ assert_equal(before_value + diff, exp.call, error)
77
108
  end
109
+
110
+ retval
78
111
  end
79
112
 
80
113
  # Assertion that the numeric result of evaluating an expression is not
81
114
  # changed before and after invoking the passed in block.
82
115
  #
83
116
  # assert_no_difference 'Article.count' do
84
- # post :create, article: invalid_attributes
117
+ # post :create, params: { article: invalid_attributes }
118
+ # end
119
+ #
120
+ # A lambda can be passed in and evaluated.
121
+ #
122
+ # assert_no_difference -> { Article.count } do
123
+ # post :create, params: { article: invalid_attributes }
85
124
  # end
86
125
  #
87
126
  # An error message can be specified.
88
127
  #
89
128
  # assert_no_difference 'Article.count', 'An Article should not be created' do
90
- # post :create, article: invalid_attributes
129
+ # post :create, params: { article: invalid_attributes }
130
+ # end
131
+ #
132
+ # An array of expressions can also be passed in and evaluated.
133
+ #
134
+ # assert_no_difference [ 'Article.count', -> { Post.count } ] do
135
+ # post :create, params: { article: invalid_attributes }
91
136
  # end
92
137
  def assert_no_difference(expression, message = nil, &block)
93
138
  assert_difference expression, 0, message, &block
94
139
  end
140
+
141
+ # Assertion that the result of evaluating an expression is changed before
142
+ # and after invoking the passed in block.
143
+ #
144
+ # assert_changes 'Status.all_good?' do
145
+ # post :create, params: { status: { ok: false } }
146
+ # end
147
+ #
148
+ # You can pass the block as a string to be evaluated in the context of
149
+ # the block. A lambda can be passed for the block as well.
150
+ #
151
+ # assert_changes -> { Status.all_good? } do
152
+ # post :create, params: { status: { ok: false } }
153
+ # end
154
+ #
155
+ # The assertion is useful to test side effects. The passed block can be
156
+ # anything that can be converted to string with #to_s.
157
+ #
158
+ # assert_changes :@object do
159
+ # @object = 42
160
+ # end
161
+ #
162
+ # The keyword arguments :from and :to can be given to specify the
163
+ # expected initial value and the expected value after the block was
164
+ # executed.
165
+ #
166
+ # assert_changes :@object, from: nil, to: :foo do
167
+ # @object = :foo
168
+ # end
169
+ #
170
+ # An error message can be specified.
171
+ #
172
+ # assert_changes -> { Status.all_good? }, 'Expected the status to be bad' do
173
+ # post :create, params: { status: { incident: true } }
174
+ # end
175
+ def assert_changes(expression, message = nil, from: UNTRACKED, to: UNTRACKED, &block)
176
+ exp = expression.respond_to?(:call) ? expression : -> { eval(expression.to_s, block.binding) }
177
+
178
+ before = exp.call
179
+ retval = assert_nothing_raised(&block)
180
+
181
+ unless from == UNTRACKED
182
+ error = "Expected change from #{from.inspect}"
183
+ error = "#{message}.\n#{error}" if message
184
+ assert from === before, error
185
+ end
186
+
187
+ after = exp.call
188
+
189
+ error = "#{expression.inspect} didn't change"
190
+ error = "#{error}. It was already #{to}" if before == to
191
+ error = "#{message}.\n#{error}" if message
192
+ refute_equal before, after, error
193
+
194
+ unless to == UNTRACKED
195
+ error = "Expected change to #{to}\n"
196
+ error = "#{message}.\n#{error}" if message
197
+ assert to === after, error
198
+ end
199
+
200
+ retval
201
+ end
202
+
203
+ # Assertion that the result of evaluating an expression is not changed before
204
+ # and after invoking the passed in block.
205
+ #
206
+ # assert_no_changes 'Status.all_good?' do
207
+ # post :create, params: { status: { ok: true } }
208
+ # end
209
+ #
210
+ # An error message can be specified.
211
+ #
212
+ # assert_no_changes -> { Status.all_good? }, 'Expected the status to be good' do
213
+ # post :create, params: { status: { ok: false } }
214
+ # end
215
+ def assert_no_changes(expression, message = nil, &block)
216
+ exp = expression.respond_to?(:call) ? expression : -> { eval(expression.to_s, block.binding) }
217
+
218
+ before = exp.call
219
+ retval = assert_nothing_raised(&block)
220
+ after = exp.call
221
+
222
+ error = "#{expression.inspect} changed"
223
+ error = "#{message}.\n#{error}" if message
224
+
225
+ if before.nil?
226
+ assert_nil after, error
227
+ else
228
+ assert_equal before, after, error
229
+ end
230
+
231
+ retval
232
+ end
95
233
  end
96
234
  end
97
235
  end
@@ -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