activesupport 4.2.11.1 → 5.2.4.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 (256) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +403 -433
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +4 -5
  5. data/lib/active_support/all.rb +5 -3
  6. data/lib/active_support/array_inquirer.rb +48 -0
  7. data/lib/active_support/backtrace_cleaner.rb +7 -5
  8. data/lib/active_support/benchmarkable.rb +6 -4
  9. data/lib/active_support/builder.rb +3 -1
  10. data/lib/active_support/cache/file_store.rb +41 -35
  11. data/lib/active_support/cache/mem_cache_store.rb +90 -91
  12. data/lib/active_support/cache/memory_store.rb +27 -30
  13. data/lib/active_support/cache/null_store.rb +7 -8
  14. data/lib/active_support/cache/redis_cache_store.rb +466 -0
  15. data/lib/active_support/cache/strategy/local_cache.rb +67 -34
  16. data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
  17. data/lib/active_support/cache.rb +287 -196
  18. data/lib/active_support/callbacks.rb +640 -590
  19. data/lib/active_support/concern.rb +11 -5
  20. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +17 -0
  21. data/lib/active_support/concurrency/share_lock.rb +227 -0
  22. data/lib/active_support/configurable.rb +8 -5
  23. data/lib/active_support/core_ext/array/access.rb +29 -1
  24. data/lib/active_support/core_ext/array/conversions.rb +22 -18
  25. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  26. data/lib/active_support/core_ext/array/grouping.rb +11 -18
  27. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  28. data/lib/active_support/core_ext/array/prepend_and_append.rb +5 -3
  29. data/lib/active_support/core_ext/array/wrap.rb +7 -4
  30. data/lib/active_support/core_ext/array.rb +9 -6
  31. data/lib/active_support/core_ext/benchmark.rb +3 -1
  32. data/lib/active_support/core_ext/big_decimal/conversions.rb +10 -12
  33. data/lib/active_support/core_ext/big_decimal.rb +3 -1
  34. data/lib/active_support/core_ext/class/attribute.rb +41 -22
  35. data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
  36. data/lib/active_support/core_ext/class/subclasses.rb +20 -6
  37. data/lib/active_support/core_ext/class.rb +4 -3
  38. data/lib/active_support/core_ext/date/acts_like.rb +3 -1
  39. data/lib/active_support/core_ext/date/blank.rb +14 -0
  40. data/lib/active_support/core_ext/date/calculations.rb +11 -9
  41. data/lib/active_support/core_ext/date/conversions.rb +25 -23
  42. data/lib/active_support/core_ext/date/zones.rb +4 -2
  43. data/lib/active_support/core_ext/date.rb +6 -4
  44. data/lib/active_support/core_ext/date_and_time/calculations.rb +170 -58
  45. data/lib/active_support/core_ext/date_and_time/compatibility.rb +4 -3
  46. data/lib/active_support/core_ext/date_and_time/zones.rb +12 -12
  47. data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
  48. data/lib/active_support/core_ext/date_time/blank.rb +14 -0
  49. data/lib/active_support/core_ext/date_time/calculations.rb +36 -18
  50. data/lib/active_support/core_ext/date_time/compatibility.rb +8 -6
  51. data/lib/active_support/core_ext/date_time/conversions.rb +16 -12
  52. data/lib/active_support/core_ext/date_time.rb +7 -5
  53. data/lib/active_support/core_ext/digest/uuid.rb +7 -5
  54. data/lib/active_support/core_ext/digest.rb +3 -0
  55. data/lib/active_support/core_ext/enumerable.rb +101 -33
  56. data/lib/active_support/core_ext/file/atomic.rb +38 -31
  57. data/lib/active_support/core_ext/file.rb +3 -1
  58. data/lib/active_support/core_ext/hash/compact.rb +14 -9
  59. data/lib/active_support/core_ext/hash/conversions.rb +62 -41
  60. data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
  61. data/lib/active_support/core_ext/hash/except.rb +11 -8
  62. data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
  63. data/lib/active_support/core_ext/hash/keys.rb +33 -27
  64. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  65. data/lib/active_support/core_ext/hash/slice.rb +8 -8
  66. data/lib/active_support/core_ext/hash/transform_values.rb +14 -5
  67. data/lib/active_support/core_ext/hash.rb +11 -9
  68. data/lib/active_support/core_ext/integer/inflections.rb +3 -1
  69. data/lib/active_support/core_ext/integer/multiple.rb +2 -0
  70. data/lib/active_support/core_ext/integer/time.rb +11 -18
  71. data/lib/active_support/core_ext/integer.rb +5 -3
  72. data/lib/active_support/core_ext/kernel/agnostics.rb +2 -0
  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 +6 -5
  77. data/lib/active_support/core_ext/load_error.rb +3 -22
  78. data/lib/active_support/core_ext/marshal.rb +8 -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 +43 -40
  83. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +150 -0
  84. data/lib/active_support/core_ext/module/concerning.rb +11 -12
  85. data/lib/active_support/core_ext/module/delegation.rb +99 -29
  86. data/lib/active_support/core_ext/module/deprecation.rb +4 -2
  87. data/lib/active_support/core_ext/module/introspection.rb +9 -9
  88. data/lib/active_support/core_ext/module/reachable.rb +5 -2
  89. data/lib/active_support/core_ext/module/redefine_method.rb +49 -0
  90. data/lib/active_support/core_ext/module/remove_method.rb +8 -3
  91. data/lib/active_support/core_ext/module.rb +14 -11
  92. data/lib/active_support/core_ext/name_error.rb +22 -2
  93. data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
  94. data/lib/active_support/core_ext/numeric/conversions.rb +78 -81
  95. data/lib/active_support/core_ext/numeric/inquiry.rb +28 -0
  96. data/lib/active_support/core_ext/numeric/time.rb +35 -23
  97. data/lib/active_support/core_ext/numeric.rb +6 -3
  98. data/lib/active_support/core_ext/object/acts_like.rb +12 -1
  99. data/lib/active_support/core_ext/object/blank.rb +27 -2
  100. data/lib/active_support/core_ext/object/conversions.rb +6 -4
  101. data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
  102. data/lib/active_support/core_ext/object/duplicable.rb +41 -14
  103. data/lib/active_support/core_ext/object/inclusion.rb +5 -3
  104. data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
  105. data/lib/active_support/core_ext/object/json.rb +49 -19
  106. data/lib/active_support/core_ext/object/to_param.rb +3 -1
  107. data/lib/active_support/core_ext/object/to_query.rb +10 -5
  108. data/lib/active_support/core_ext/object/try.rb +69 -21
  109. data/lib/active_support/core_ext/object/with_options.rb +16 -3
  110. data/lib/active_support/core_ext/object.rb +14 -13
  111. data/lib/active_support/core_ext/range/compare_range.rb +61 -0
  112. data/lib/active_support/core_ext/range/conversions.rb +27 -7
  113. data/lib/active_support/core_ext/range/each.rb +19 -17
  114. data/lib/active_support/core_ext/range/include_range.rb +2 -22
  115. data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
  116. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  117. data/lib/active_support/core_ext/range.rb +7 -4
  118. data/lib/active_support/core_ext/regexp.rb +6 -0
  119. data/lib/active_support/core_ext/securerandom.rb +25 -0
  120. data/lib/active_support/core_ext/string/access.rb +8 -6
  121. data/lib/active_support/core_ext/string/behavior.rb +3 -1
  122. data/lib/active_support/core_ext/string/conversions.rb +7 -4
  123. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  124. data/lib/active_support/core_ext/string/filters.rb +6 -5
  125. data/lib/active_support/core_ext/string/indent.rb +6 -4
  126. data/lib/active_support/core_ext/string/inflections.rb +61 -24
  127. data/lib/active_support/core_ext/string/inquiry.rb +3 -1
  128. data/lib/active_support/core_ext/string/multibyte.rb +15 -7
  129. data/lib/active_support/core_ext/string/output_safety.rb +34 -38
  130. data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
  131. data/lib/active_support/core_ext/string/strip.rb +4 -5
  132. data/lib/active_support/core_ext/string/zones.rb +4 -2
  133. data/lib/active_support/core_ext/string.rb +15 -13
  134. data/lib/active_support/core_ext/time/acts_like.rb +3 -1
  135. data/lib/active_support/core_ext/time/calculations.rb +85 -51
  136. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  137. data/lib/active_support/core_ext/time/conversions.rb +20 -13
  138. data/lib/active_support/core_ext/time/zones.rb +41 -7
  139. data/lib/active_support/core_ext/time.rb +7 -6
  140. data/lib/active_support/core_ext/uri.rb +6 -8
  141. data/lib/active_support/core_ext.rb +3 -1
  142. data/lib/active_support/current_attributes.rb +195 -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.rb +152 -161
  146. data/lib/active_support/deprecation/behaviors.rb +44 -11
  147. data/lib/active_support/deprecation/constant_accessor.rb +52 -0
  148. data/lib/active_support/deprecation/instance_delegator.rb +17 -2
  149. data/lib/active_support/deprecation/method_wrappers.rb +66 -20
  150. data/lib/active_support/deprecation/proxy_wrappers.rb +56 -28
  151. data/lib/active_support/deprecation/reporting.rb +32 -12
  152. data/lib/active_support/deprecation.rb +12 -9
  153. data/lib/active_support/descendants_tracker.rb +2 -0
  154. data/lib/active_support/digest.rb +20 -0
  155. data/lib/active_support/duration/iso8601_parser.rb +125 -0
  156. data/lib/active_support/duration/iso8601_serializer.rb +55 -0
  157. data/lib/active_support/duration.rb +307 -35
  158. data/lib/active_support/encrypted_configuration.rb +49 -0
  159. data/lib/active_support/encrypted_file.rb +99 -0
  160. data/lib/active_support/evented_file_update_checker.rb +205 -0
  161. data/lib/active_support/execution_wrapper.rb +128 -0
  162. data/lib/active_support/executor.rb +8 -0
  163. data/lib/active_support/file_update_checker.rb +63 -37
  164. data/lib/active_support/gem_version.rb +6 -4
  165. data/lib/active_support/gzip.rb +7 -5
  166. data/lib/active_support/hash_with_indifferent_access.rb +123 -28
  167. data/lib/active_support/i18n.rb +8 -6
  168. data/lib/active_support/i18n_railtie.rb +37 -13
  169. data/lib/active_support/inflections.rb +13 -11
  170. data/lib/active_support/inflector/inflections.rb +61 -12
  171. data/lib/active_support/inflector/methods.rb +163 -136
  172. data/lib/active_support/inflector/transliterate.rb +48 -27
  173. data/lib/active_support/inflector.rb +7 -5
  174. data/lib/active_support/json/decoding.rb +16 -13
  175. data/lib/active_support/json/encoding.rb +11 -58
  176. data/lib/active_support/json.rb +4 -2
  177. data/lib/active_support/key_generator.rb +25 -25
  178. data/lib/active_support/lazy_load_hooks.rb +50 -20
  179. data/lib/active_support/locale/en.yml +2 -0
  180. data/lib/active_support/log_subscriber/test_helper.rb +14 -12
  181. data/lib/active_support/log_subscriber.rb +13 -10
  182. data/lib/active_support/logger.rb +8 -7
  183. data/lib/active_support/logger_silence.rb +6 -4
  184. data/lib/active_support/logger_thread_safe_level.rb +7 -5
  185. data/lib/active_support/message_encryptor.rb +168 -53
  186. data/lib/active_support/message_verifier.rb +150 -17
  187. data/lib/active_support/messages/metadata.rb +71 -0
  188. data/lib/active_support/messages/rotation_configuration.rb +22 -0
  189. data/lib/active_support/messages/rotator.rb +56 -0
  190. data/lib/active_support/multibyte/chars.rb +36 -23
  191. data/lib/active_support/multibyte/unicode.rb +100 -96
  192. data/lib/active_support/multibyte.rb +4 -2
  193. data/lib/active_support/notifications/fanout.rb +11 -9
  194. data/lib/active_support/notifications/instrumenter.rb +27 -7
  195. data/lib/active_support/notifications.rb +11 -7
  196. data/lib/active_support/number_helper/number_converter.rb +13 -11
  197. data/lib/active_support/number_helper/number_to_currency_converter.rb +9 -9
  198. data/lib/active_support/number_helper/number_to_delimited_converter.rb +9 -3
  199. data/lib/active_support/number_helper/number_to_human_converter.rb +11 -9
  200. data/lib/active_support/number_helper/number_to_human_size_converter.rb +9 -8
  201. data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
  202. data/lib/active_support/number_helper/number_to_phone_converter.rb +13 -4
  203. data/lib/active_support/number_helper/number_to_rounded_converter.rb +23 -56
  204. data/lib/active_support/number_helper/rounding_helper.rb +66 -0
  205. data/lib/active_support/number_helper.rb +94 -68
  206. data/lib/active_support/option_merger.rb +3 -1
  207. data/lib/active_support/ordered_hash.rb +6 -4
  208. data/lib/active_support/ordered_options.rb +23 -5
  209. data/lib/active_support/per_thread_registry.rb +9 -4
  210. data/lib/active_support/proxy_object.rb +2 -0
  211. data/lib/active_support/rails.rb +16 -8
  212. data/lib/active_support/railtie.rb +43 -9
  213. data/lib/active_support/reloader.rb +131 -0
  214. data/lib/active_support/rescuable.rb +108 -53
  215. data/lib/active_support/security_utils.rb +15 -11
  216. data/lib/active_support/string_inquirer.rb +11 -3
  217. data/lib/active_support/subscriber.rb +21 -16
  218. data/lib/active_support/tagged_logging.rb +14 -11
  219. data/lib/active_support/test_case.rb +19 -47
  220. data/lib/active_support/testing/assertions.rb +137 -20
  221. data/lib/active_support/testing/autorun.rb +4 -2
  222. data/lib/active_support/testing/constant_lookup.rb +2 -1
  223. data/lib/active_support/testing/declarative.rb +3 -1
  224. data/lib/active_support/testing/deprecation.rb +14 -10
  225. data/lib/active_support/testing/file_fixtures.rb +36 -0
  226. data/lib/active_support/testing/isolation.rb +34 -25
  227. data/lib/active_support/testing/method_call_assertions.rb +43 -0
  228. data/lib/active_support/testing/setup_and_teardown.rb +13 -8
  229. data/lib/active_support/testing/stream.rb +44 -0
  230. data/lib/active_support/testing/tagged_logging.rb +3 -1
  231. data/lib/active_support/testing/time_helpers.rb +81 -15
  232. data/lib/active_support/time.rb +14 -12
  233. data/lib/active_support/time_with_zone.rb +169 -39
  234. data/lib/active_support/values/time_zone.rb +196 -61
  235. data/lib/active_support/values/unicode_tables.dat +0 -0
  236. data/lib/active_support/version.rb +3 -1
  237. data/lib/active_support/xml_mini/jdom.rb +116 -114
  238. data/lib/active_support/xml_mini/libxml.rb +16 -13
  239. data/lib/active_support/xml_mini/libxmlsax.rb +15 -14
  240. data/lib/active_support/xml_mini/nokogiri.rb +14 -12
  241. data/lib/active_support/xml_mini/nokogirisax.rb +14 -13
  242. data/lib/active_support/xml_mini/rexml.rb +11 -9
  243. data/lib/active_support/xml_mini.rb +37 -37
  244. data/lib/active_support.rb +12 -11
  245. metadata +54 -24
  246. data/lib/active_support/concurrency/latch.rb +0 -27
  247. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
  248. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
  249. data/lib/active_support/core_ext/date_time/zones.rb +0 -6
  250. data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
  251. data/lib/active_support/core_ext/module/method_transplanting.rb +0 -13
  252. data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
  253. data/lib/active_support/core_ext/object/itself.rb +0 -15
  254. data/lib/active_support/core_ext/struct.rb +0 -6
  255. data/lib/active_support/core_ext/thread.rb +0 -86
  256. data/lib/active_support/core_ext/time/marshal.rb +0 -30
@@ -1,9 +1,11 @@
1
- require 'active_support/core_ext/object/blank'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module ActiveSupport
4
4
  module Testing
5
5
  module Assertions
6
- # Assert that an expression is not truthy. Passes if <tt>object</tt> is
6
+ UNTRACKED = Object.new # :nodoc:
7
+
8
+ # Asserts that an expression is not truthy. Passes if <tt>object</tt> is
7
9
  # +nil+ or +false+. "Truthy" means "considered true in a conditional"
8
10
  # like <tt>if foo</tt>.
9
11
  #
@@ -19,79 +21,194 @@ module ActiveSupport
19
21
  assert !object, message
20
22
  end
21
23
 
24
+ # Assertion that the block should not raise an exception.
25
+ #
26
+ # Passes if evaluated code in the yielded block raises no exception.
27
+ #
28
+ # assert_nothing_raised do
29
+ # perform_service(param: 'no_exception')
30
+ # end
31
+ def assert_nothing_raised
32
+ yield
33
+ end
34
+
22
35
  # Test numeric difference between the return value of an expression as a
23
36
  # result of what is evaluated in the yielded block.
24
37
  #
25
38
  # assert_difference 'Article.count' do
26
- # post :create, article: {...}
39
+ # post :create, params: { article: {...} }
27
40
  # end
28
41
  #
29
42
  # An arbitrary expression is passed in and evaluated.
30
43
  #
31
- # assert_difference 'assigns(:article).comments(:reload).size' do
32
- # post :create, comment: {...}
44
+ # assert_difference 'Article.last.comments(:reload).size' do
45
+ # post :create, params: { comment: {...} }
33
46
  # end
34
47
  #
35
48
  # An arbitrary positive or negative difference can be specified.
36
49
  # The default is <tt>1</tt>.
37
50
  #
38
51
  # assert_difference 'Article.count', -1 do
39
- # post :delete, id: ...
52
+ # post :delete, params: { id: ... }
40
53
  # end
41
54
  #
42
55
  # An array of expressions can also be passed in and evaluated.
43
56
  #
44
57
  # assert_difference [ 'Article.count', 'Post.count' ], 2 do
45
- # post :create, article: {...}
58
+ # post :create, params: { article: {...} }
59
+ # end
60
+ #
61
+ # A hash of expressions/numeric differences can also be passed in and evaluated.
62
+ #
63
+ # assert_difference ->{ Article.count } => 1, ->{ Notification.count } => 2 do
64
+ # post :create, params: { article: {...} }
46
65
  # end
47
66
  #
48
67
  # A lambda or a list of lambdas can be passed in and evaluated:
49
68
  #
50
69
  # assert_difference ->{ Article.count }, 2 do
51
- # post :create, article: {...}
70
+ # post :create, params: { article: {...} }
52
71
  # end
53
72
  #
54
73
  # assert_difference [->{ Article.count }, ->{ Post.count }], 2 do
55
- # post :create, article: {...}
74
+ # post :create, params: { article: {...} }
56
75
  # end
57
76
  #
58
77
  # An error message can be specified.
59
78
  #
60
79
  # assert_difference 'Article.count', -1, 'An Article should be destroyed' do
61
- # post :delete, id: ...
80
+ # post :delete, params: { id: ... }
62
81
  # end
63
- def assert_difference(expression, difference = 1, message = nil, &block)
64
- expressions = Array(expression)
82
+ def assert_difference(expression, *args, &block)
83
+ expressions =
84
+ if expression.is_a?(Hash)
85
+ message = args[0]
86
+ expression
87
+ else
88
+ difference = args[0] || 1
89
+ message = args[1]
90
+ Hash[Array(expression).map { |e| [e, difference] }]
91
+ end
65
92
 
66
- exps = expressions.map { |e|
93
+ exps = expressions.keys.map { |e|
67
94
  e.respond_to?(:call) ? e : lambda { eval(e, block.binding) }
68
95
  }
69
- before = exps.map { |e| e.call }
96
+ before = exps.map(&:call)
70
97
 
71
- yield
98
+ retval = yield
72
99
 
73
- expressions.zip(exps).each_with_index do |(code, e), i|
74
- error = "#{code.inspect} didn't change by #{difference}"
100
+ expressions.zip(exps, before) do |(code, diff), exp, before_value|
101
+ error = "#{code.inspect} didn't change by #{diff}"
75
102
  error = "#{message}.\n#{error}" if message
76
- assert_equal(before[i] + difference, e.call, error)
103
+ assert_equal(before_value + diff, exp.call, error)
77
104
  end
105
+
106
+ retval
78
107
  end
79
108
 
80
109
  # Assertion that the numeric result of evaluating an expression is not
81
110
  # changed before and after invoking the passed in block.
82
111
  #
83
112
  # assert_no_difference 'Article.count' do
84
- # post :create, article: invalid_attributes
113
+ # post :create, params: { article: invalid_attributes }
85
114
  # end
86
115
  #
87
116
  # An error message can be specified.
88
117
  #
89
118
  # assert_no_difference 'Article.count', 'An Article should not be created' do
90
- # post :create, article: invalid_attributes
119
+ # post :create, params: { article: invalid_attributes }
91
120
  # end
92
121
  def assert_no_difference(expression, message = nil, &block)
93
122
  assert_difference expression, 0, message, &block
94
123
  end
124
+
125
+ # Assertion that the result of evaluating an expression is changed before
126
+ # and after invoking the passed in block.
127
+ #
128
+ # assert_changes 'Status.all_good?' do
129
+ # post :create, params: { status: { ok: false } }
130
+ # end
131
+ #
132
+ # You can pass the block as a string to be evaluated in the context of
133
+ # the block. A lambda can be passed for the block as well.
134
+ #
135
+ # assert_changes -> { Status.all_good? } do
136
+ # post :create, params: { status: { ok: false } }
137
+ # end
138
+ #
139
+ # The assertion is useful to test side effects. The passed block can be
140
+ # anything that can be converted to string with #to_s.
141
+ #
142
+ # assert_changes :@object do
143
+ # @object = 42
144
+ # end
145
+ #
146
+ # The keyword arguments :from and :to can be given to specify the
147
+ # expected initial value and the expected value after the block was
148
+ # executed.
149
+ #
150
+ # assert_changes :@object, from: nil, to: :foo do
151
+ # @object = :foo
152
+ # end
153
+ #
154
+ # An error message can be specified.
155
+ #
156
+ # assert_changes -> { Status.all_good? }, 'Expected the status to be bad' do
157
+ # post :create, params: { status: { incident: true } }
158
+ # end
159
+ def assert_changes(expression, message = nil, from: UNTRACKED, to: UNTRACKED, &block)
160
+ exp = expression.respond_to?(:call) ? expression : -> { eval(expression.to_s, block.binding) }
161
+
162
+ before = exp.call
163
+ retval = yield
164
+
165
+ unless from == UNTRACKED
166
+ error = "#{expression.inspect} isn't #{from.inspect}"
167
+ error = "#{message}.\n#{error}" if message
168
+ assert from === before, error
169
+ end
170
+
171
+ after = exp.call
172
+
173
+ error = "#{expression.inspect} didn't change"
174
+ error = "#{error}. It was already #{to}" if before == to
175
+ error = "#{message}.\n#{error}" if message
176
+ assert before != after, error
177
+
178
+ unless to == UNTRACKED
179
+ error = "#{expression.inspect} didn't change to #{to}"
180
+ error = "#{message}.\n#{error}" if message
181
+ assert to === after, error
182
+ end
183
+
184
+ retval
185
+ end
186
+
187
+ # Assertion that the result of evaluating an expression is not changed before
188
+ # and after invoking the passed in block.
189
+ #
190
+ # assert_no_changes 'Status.all_good?' do
191
+ # post :create, params: { status: { ok: true } }
192
+ # end
193
+ #
194
+ # An error message can be specified.
195
+ #
196
+ # assert_no_changes -> { Status.all_good? }, 'Expected the status to be good' do
197
+ # post :create, params: { status: { ok: false } }
198
+ # end
199
+ def assert_no_changes(expression, message = nil, &block)
200
+ exp = expression.respond_to?(:call) ? expression : -> { eval(expression.to_s, block.binding) }
201
+
202
+ before = exp.call
203
+ retval = yield
204
+ after = exp.call
205
+
206
+ error = "#{expression.inspect} did change to #{after}"
207
+ error = "#{message}.\n#{error}" if message
208
+ assert before == after, error
209
+
210
+ retval
211
+ end
95
212
  end
96
213
  end
97
214
  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,38 @@
1
- require 'active_support/deprecation'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/deprecation"
4
+ require "active_support/core_ext/regexp"
2
5
 
3
6
  module ActiveSupport
4
7
  module Testing
5
8
  module Deprecation #:nodoc:
6
- def assert_deprecated(match = nil, &block)
7
- result, warnings = collect_deprecations(&block)
9
+ def assert_deprecated(match = nil, deprecator = nil, &block)
10
+ result, warnings = collect_deprecations(deprecator, &block)
8
11
  assert !warnings.empty?, "Expected a deprecation warning within the block but received none"
9
12
  if match
10
13
  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(', ')}"
14
+ assert warnings.any? { |w| match.match?(w) }, "No deprecation warning matched #{match}: #{warnings.join(', ')}"
12
15
  end
13
16
  result
14
17
  end
15
18
 
16
- def assert_not_deprecated(&block)
17
- result, deprecations = collect_deprecations(&block)
19
+ def assert_not_deprecated(deprecator = nil, &block)
20
+ result, deprecations = collect_deprecations(deprecator, &block)
18
21
  assert deprecations.empty?, "Expected no deprecation warning within the block but received #{deprecations.size}: \n #{deprecations * "\n "}"
19
22
  result
20
23
  end
21
24
 
22
- def collect_deprecations
23
- old_behavior = ActiveSupport::Deprecation.behavior
25
+ def collect_deprecations(deprecator = nil)
26
+ deprecator ||= ActiveSupport::Deprecation
27
+ old_behavior = deprecator.behavior
24
28
  deprecations = []
25
- ActiveSupport::Deprecation.behavior = Proc.new do |message, callstack|
29
+ deprecator.behavior = Proc.new do |message, callstack|
26
30
  deprecations << message
27
31
  end
28
32
  result = yield
29
33
  [result, deprecations]
30
34
  ensure
31
- ActiveSupport::Deprecation.behavior = old_behavior
35
+ deprecator.behavior = old_behavior
32
36
  end
33
37
  end
34
38
  end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ module Testing
5
+ # Adds simple access to sample files called file fixtures.
6
+ # File fixtures are normal files stored in
7
+ # <tt>ActiveSupport::TestCase.file_fixture_path</tt>.
8
+ #
9
+ # File fixtures are represented as +Pathname+ objects.
10
+ # This makes it easy to extract specific information:
11
+ #
12
+ # file_fixture("example.txt").read # get the file's content
13
+ # file_fixture("example.mp3").size # get the file size
14
+ module FileFixtures
15
+ extend ActiveSupport::Concern
16
+
17
+ included do
18
+ class_attribute :file_fixture_path, instance_writer: false
19
+ end
20
+
21
+ # Returns a +Pathname+ to the fixture file named +fixture_name+.
22
+ #
23
+ # Raises +ArgumentError+ if +fixture_name+ can't be found.
24
+ def file_fixture(fixture_name)
25
+ path = Pathname.new(File.join(file_fixture_path, fixture_name))
26
+
27
+ if path.exist?
28
+ path
29
+ else
30
+ msg = "the directory '%s' does not contain a file named '%s'"
31
+ raise ArgumentError, msg % [file_fixture_path, fixture_name]
32
+ end
33
+ end
34
+ end
35
+ end
36
+ 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.unpack("m")[0]
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)
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "minitest/mock"
4
+
5
+ module ActiveSupport
6
+ module Testing
7
+ module MethodCallAssertions # :nodoc:
8
+ private
9
+ def assert_called(object, method_name, message = nil, times: 1, returns: nil)
10
+ times_called = 0
11
+
12
+ object.stub(method_name, proc { times_called += 1; returns }) { yield }
13
+
14
+ error = "Expected #{method_name} to be called #{times} times, " \
15
+ "but was called #{times_called} times"
16
+ error = "#{message}.\n#{error}" if message
17
+ assert_equal times, times_called, error
18
+ end
19
+
20
+ def assert_called_with(object, method_name, args = [], returns: nil)
21
+ mock = Minitest::Mock.new
22
+
23
+ if args.all? { |arg| arg.is_a?(Array) }
24
+ args.each { |arg| mock.expect(:call, returns, arg) }
25
+ else
26
+ mock.expect(:call, returns, args)
27
+ end
28
+
29
+ object.stub(method_name, mock) { yield }
30
+
31
+ mock.verify
32
+ end
33
+
34
+ def assert_not_called(object, method_name, message = nil, &block)
35
+ assert_called(object, method_name, message, times: 0, &block)
36
+ end
37
+
38
+ def stub_any_instance(klass, instance: klass.new)
39
+ klass.stub(:new, instance) { yield instance }
40
+ end
41
+ end
42
+ end
43
+ end
@@ -1,5 +1,6 @@
1
- require 'active_support/concern'
2
- require 'active_support/callbacks'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/callbacks"
3
4
 
4
5
  module ActiveSupport
5
6
  module Testing
@@ -17,11 +18,10 @@ module ActiveSupport
17
18
  # end
18
19
  # end
19
20
  module SetupAndTeardown
20
- extend ActiveSupport::Concern
21
-
22
- included do
23
- include ActiveSupport::Callbacks
24
- define_callbacks :setup, :teardown
21
+ def self.prepended(klass)
22
+ klass.include ActiveSupport::Callbacks
23
+ klass.define_callbacks :setup, :teardown
24
+ klass.extend ClassMethods
25
25
  end
26
26
 
27
27
  module ClassMethods
@@ -42,7 +42,12 @@ module ActiveSupport
42
42
  end
43
43
 
44
44
  def after_teardown # :nodoc:
45
- run_callbacks :teardown
45
+ begin
46
+ run_callbacks :teardown
47
+ rescue => e
48
+ self.failures << Minitest::UnexpectedError.new(e)
49
+ end
50
+
46
51
  super
47
52
  end
48
53
  end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ module Testing
5
+ module Stream #:nodoc:
6
+ private
7
+
8
+ def silence_stream(stream)
9
+ old_stream = stream.dup
10
+ stream.reopen(IO::NULL)
11
+ stream.sync = true
12
+ yield
13
+ ensure
14
+ stream.reopen(old_stream)
15
+ old_stream.close
16
+ end
17
+
18
+ def quietly
19
+ silence_stream(STDOUT) do
20
+ silence_stream(STDERR) do
21
+ yield
22
+ end
23
+ end
24
+ end
25
+
26
+ def capture(stream)
27
+ stream = stream.to_s
28
+ captured_stream = Tempfile.new(stream)
29
+ stream_io = eval("$#{stream}")
30
+ origin_stream = stream_io.dup
31
+ stream_io.reopen(captured_stream)
32
+
33
+ yield
34
+
35
+ stream_io.rewind
36
+ return captured_stream.read
37
+ ensure
38
+ captured_stream.close
39
+ captured_stream.unlink
40
+ stream_io.reopen(origin_stream)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  module Testing
3
5
  # Logs a "PostsControllerTest: test name" heading before each test to
@@ -8,7 +10,7 @@ module ActiveSupport
8
10
  def before_setup
9
11
  if tagged_logger && tagged_logger.info?
10
12
  heading = "#{self.class}: #{name}"
11
- divider = '-' * heading.size
13
+ divider = "-" * heading.size
12
14
  tagged_logger.info divider
13
15
  tagged_logger.info heading
14
16
  tagged_logger.info divider