activesupport 4.0.13 → 5.2.5

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 (264) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +412 -444
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +8 -4
  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 +14 -12
  8. data/lib/active_support/benchmarkable.rb +6 -14
  9. data/lib/active_support/builder.rb +3 -1
  10. data/lib/active_support/cache/file_store.rb +67 -51
  11. data/lib/active_support/cache/mem_cache_store.rb +95 -97
  12. data/lib/active_support/cache/memory_store.rb +28 -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 +70 -56
  16. data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
  17. data/lib/active_support/cache.rb +331 -206
  18. data/lib/active_support/callbacks.rb +697 -426
  19. data/lib/active_support/concern.rb +32 -10
  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 +39 -1
  24. data/lib/active_support/core_ext/array/conversions.rb +24 -35
  25. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  26. data/lib/active_support/core_ext/array/grouping.rb +23 -13
  27. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  28. data/lib/active_support/core_ext/array/prepend_and_append.rb +7 -5
  29. data/lib/active_support/core_ext/array/wrap.rb +7 -4
  30. data/lib/active_support/core_ext/array.rb +9 -7
  31. data/lib/active_support/core_ext/benchmark.rb +3 -1
  32. data/lib/active_support/core_ext/big_decimal/conversions.rb +9 -26
  33. data/lib/active_support/core_ext/big_decimal.rb +3 -1
  34. data/lib/active_support/core_ext/class/attribute.rb +41 -23
  35. data/lib/active_support/core_ext/class/attribute_accessors.rb +5 -169
  36. data/lib/active_support/core_ext/class/subclasses.rb +20 -8
  37. data/lib/active_support/core_ext/class.rb +4 -4
  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 +21 -9
  41. data/lib/active_support/core_ext/date/conversions.rb +32 -22
  42. data/lib/active_support/core_ext/date/zones.rb +5 -34
  43. data/lib/active_support/core_ext/date.rb +6 -4
  44. data/lib/active_support/core_ext/date_and_time/calculations.rb +199 -57
  45. data/lib/active_support/core_ext/date_and_time/compatibility.rb +16 -0
  46. data/lib/active_support/core_ext/date_and_time/zones.rb +41 -0
  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 +78 -37
  50. data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
  51. data/lib/active_support/core_ext/date_time/conversions.rb +19 -13
  52. data/lib/active_support/core_ext/date_time.rb +7 -4
  53. data/lib/active_support/core_ext/digest/uuid.rb +53 -0
  54. data/lib/active_support/core_ext/digest.rb +3 -0
  55. data/lib/active_support/core_ext/enumerable.rb +113 -29
  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 +29 -0
  59. data/lib/active_support/core_ext/hash/conversions.rb +71 -49
  60. data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
  61. data/lib/active_support/core_ext/hash/except.rb +12 -3
  62. data/lib/active_support/core_ext/hash/indifferent_access.rb +5 -3
  63. data/lib/active_support/core_ext/hash/keys.rb +50 -38
  64. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  65. data/lib/active_support/core_ext/hash/slice.rb +12 -6
  66. data/lib/active_support/core_ext/hash/transform_values.rb +32 -0
  67. data/lib/active_support/core_ext/hash.rb +11 -8
  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 -33
  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 +14 -0
  74. data/lib/active_support/core_ext/kernel/reporting.rb +5 -74
  75. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  76. data/lib/active_support/core_ext/kernel.rb +6 -4
  77. data/lib/active_support/core_ext/load_error.rb +5 -21
  78. data/lib/active_support/core_ext/marshal.rb +13 -10
  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 -8
  82. data/lib/active_support/core_ext/module/attribute_accessors.rb +170 -21
  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 +134 -0
  85. data/lib/active_support/core_ext/module/delegation.rb +135 -45
  86. data/lib/active_support/core_ext/module/deprecation.rb +3 -3
  87. data/lib/active_support/core_ext/module/introspection.rb +9 -25
  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 -10
  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 +79 -74
  95. data/lib/active_support/core_ext/numeric/inquiry.rb +28 -0
  96. data/lib/active_support/core_ext/numeric/time.rb +37 -50
  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 +70 -19
  100. data/lib/active_support/core_ext/object/conversions.rb +6 -4
  101. data/lib/active_support/core_ext/object/deep_dup.rb +19 -10
  102. data/lib/active_support/core_ext/object/duplicable.rb +100 -34
  103. data/lib/active_support/core_ext/object/inclusion.rb +18 -15
  104. data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
  105. data/lib/active_support/core_ext/object/json.rb +227 -0
  106. data/lib/active_support/core_ext/object/to_param.rb +3 -1
  107. data/lib/active_support/core_ext/object/to_query.rb +21 -8
  108. data/lib/active_support/core_ext/object/try.rb +94 -24
  109. data/lib/active_support/core_ext/object/with_options.rb +45 -5
  110. data/lib/active_support/core_ext/object.rb +14 -12
  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 +41 -39
  121. data/lib/active_support/core_ext/string/behavior.rb +3 -1
  122. data/lib/active_support/core_ext/string/conversions.rb +17 -13
  123. data/lib/active_support/core_ext/string/exclude.rb +5 -3
  124. data/lib/active_support/core_ext/string/filters.rb +55 -6
  125. data/lib/active_support/core_ext/string/indent.rb +6 -4
  126. data/lib/active_support/core_ext/string/inflections.rb +66 -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 +114 -54
  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 -1
  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 +123 -110
  136. data/lib/active_support/core_ext/time/compatibility.rb +16 -0
  137. data/lib/active_support/core_ext/time/conversions.rb +23 -14
  138. data/lib/active_support/core_ext/time/zones.rb +42 -26
  139. data/lib/active_support/core_ext/time.rb +7 -5
  140. data/lib/active_support/core_ext/uri.rb +6 -8
  141. data/lib/active_support/core_ext.rb +3 -2
  142. data/lib/active_support/current_attributes.rb +195 -0
  143. data/lib/active_support/dependencies/autoload.rb +3 -1
  144. data/lib/active_support/dependencies/interlock.rb +57 -0
  145. data/lib/active_support/dependencies.rb +196 -166
  146. data/lib/active_support/deprecation/behaviors.rb +48 -15
  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 +14 -11
  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 +354 -34
  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 +17 -0
  165. data/lib/active_support/gzip.rb +7 -5
  166. data/lib/active_support/hash_with_indifferent_access.rb +158 -35
  167. data/lib/active_support/i18n.rb +8 -6
  168. data/lib/active_support/i18n_railtie.rb +38 -20
  169. data/lib/active_support/inflections.rb +19 -12
  170. data/lib/active_support/inflector/inflections.rb +79 -30
  171. data/lib/active_support/inflector/methods.rb +197 -129
  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 +21 -25
  175. data/lib/active_support/json/encoding.rb +84 -292
  176. data/lib/active_support/json.rb +4 -2
  177. data/lib/active_support/key_generator.rb +26 -28
  178. data/lib/active_support/lazy_load_hooks.rb +51 -21
  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 +54 -3
  183. data/lib/active_support/logger_silence.rb +12 -7
  184. data/lib/active_support/logger_thread_safe_level.rb +34 -0
  185. data/lib/active_support/message_encryptor.rb +173 -50
  186. data/lib/active_support/message_verifier.rb +159 -22
  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 +38 -26
  191. data/lib/active_support/multibyte/unicode.rb +138 -146
  192. data/lib/active_support/multibyte.rb +4 -2
  193. data/lib/active_support/notifications/fanout.rb +23 -16
  194. data/lib/active_support/notifications/instrumenter.rb +29 -8
  195. data/lib/active_support/notifications.rb +22 -13
  196. data/lib/active_support/number_helper/number_converter.rb +184 -0
  197. data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
  198. data/lib/active_support/number_helper/number_to_delimited_converter.rb +29 -0
  199. data/lib/active_support/number_helper/number_to_human_converter.rb +68 -0
  200. data/lib/active_support/number_helper/number_to_human_size_converter.rb +59 -0
  201. data/lib/active_support/number_helper/number_to_percentage_converter.rb +14 -0
  202. data/lib/active_support/number_helper/number_to_phone_converter.rb +58 -0
  203. data/lib/active_support/number_helper/number_to_rounded_converter.rb +54 -0
  204. data/lib/active_support/number_helper/rounding_helper.rb +66 -0
  205. data/lib/active_support/number_helper.rb +125 -391
  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 +31 -5
  209. data/lib/active_support/per_thread_registry.rb +19 -11
  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 +31 -0
  216. data/lib/active_support/string_inquirer.rb +11 -3
  217. data/lib/active_support/subscriber.rb +54 -17
  218. data/lib/active_support/tagged_logging.rb +14 -11
  219. data/lib/active_support/test_case.rb +42 -37
  220. data/lib/active_support/testing/assertions.rb +126 -39
  221. data/lib/active_support/testing/autorun.rb +5 -3
  222. data/lib/active_support/testing/constant_lookup.rb +3 -6
  223. data/lib/active_support/testing/declarative.rb +10 -22
  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 +55 -86
  227. data/lib/active_support/testing/method_call_assertions.rb +43 -0
  228. data/lib/active_support/testing/setup_and_teardown.rb +30 -10
  229. data/lib/active_support/testing/stream.rb +44 -0
  230. data/lib/active_support/testing/tagged_logging.rb +5 -3
  231. data/lib/active_support/testing/time_helpers.rb +200 -0
  232. data/lib/active_support/time.rb +13 -13
  233. data/lib/active_support/time_with_zone.rb +223 -73
  234. data/lib/active_support/values/time_zone.rb +261 -126
  235. data/lib/active_support/values/unicode_tables.dat +0 -0
  236. data/lib/active_support/version.rb +6 -7
  237. data/lib/active_support/xml_mini/jdom.rb +116 -113
  238. data/lib/active_support/xml_mini/libxml.rb +17 -16
  239. data/lib/active_support/xml_mini/libxmlsax.rb +16 -18
  240. data/lib/active_support/xml_mini/nokogiri.rb +15 -15
  241. data/lib/active_support/xml_mini/nokogirisax.rb +15 -16
  242. data/lib/active_support/xml_mini/rexml.rb +17 -16
  243. data/lib/active_support/xml_mini.rb +69 -51
  244. data/lib/active_support.rb +29 -3
  245. metadata +84 -54
  246. data/lib/active_support/basic_object.rb +0 -11
  247. data/lib/active_support/buffered_logger.rb +0 -21
  248. data/lib/active_support/concurrency/latch.rb +0 -27
  249. data/lib/active_support/core_ext/array/uniq_by.rb +0 -19
  250. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -40
  251. data/lib/active_support/core_ext/date_time/zones.rb +0 -24
  252. data/lib/active_support/core_ext/hash/diff.rb +0 -14
  253. data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
  254. data/lib/active_support/core_ext/logger.rb +0 -67
  255. data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
  256. data/lib/active_support/core_ext/object/to_json.rb +0 -27
  257. data/lib/active_support/core_ext/proc.rb +0 -17
  258. data/lib/active_support/core_ext/string/encoding.rb +0 -8
  259. data/lib/active_support/core_ext/struct.rb +0 -6
  260. data/lib/active_support/core_ext/thread.rb +0 -79
  261. data/lib/active_support/core_ext/time/marshal.rb +0 -30
  262. data/lib/active_support/file_watcher.rb +0 -36
  263. data/lib/active_support/json/variable.rb +0 -18
  264. data/lib/active_support/testing/pending.rb +0 -14
@@ -1,57 +1,90 @@
1
- require 'active_support/per_thread_registry'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/per_thread_registry"
4
+ require "active_support/notifications"
2
5
 
3
6
  module ActiveSupport
4
7
  # ActiveSupport::Subscriber is an object set to consume
5
8
  # ActiveSupport::Notifications. The subscriber dispatches notifications to
6
9
  # a registered object based on its given namespace.
7
10
  #
8
- # An example would be Active Record subscriber responsible for collecting
11
+ # An example would be an Active Record subscriber responsible for collecting
9
12
  # statistics about queries:
10
13
  #
11
14
  # module ActiveRecord
12
15
  # class StatsSubscriber < ActiveSupport::Subscriber
16
+ # attach_to :active_record
17
+ #
13
18
  # def sql(event)
14
19
  # Statsd.timing("sql.#{event.payload[:name]}", event.duration)
15
20
  # end
16
21
  # end
17
22
  # end
18
23
  #
19
- # And it's finally registered as:
20
- #
21
- # ActiveRecord::StatsSubscriber.attach_to :active_record
22
- #
23
- # Since we need to know all instance methods before attaching the log
24
- # subscriber, the line above should be called after your subscriber definition.
25
- #
26
24
  # After configured, whenever a "sql.active_record" notification is published,
27
25
  # it will properly dispatch the event (ActiveSupport::Notifications::Event) to
28
26
  # the +sql+ method.
29
27
  class Subscriber
30
28
  class << self
31
-
32
29
  # Attach the subscriber to a namespace.
33
- def attach_to(namespace, subscriber=new, notifier=ActiveSupport::Notifications)
30
+ def attach_to(namespace, subscriber = new, notifier = ActiveSupport::Notifications)
31
+ @namespace = namespace
32
+ @subscriber = subscriber
33
+ @notifier = notifier
34
+
34
35
  subscribers << subscriber
35
36
 
37
+ # Add event subscribers for all existing methods on the class.
36
38
  subscriber.public_methods(false).each do |event|
37
- next if %w{ start finish }.include?(event.to_s)
39
+ add_event_subscriber(event)
40
+ end
41
+ end
38
42
 
39
- notifier.subscribe("#{event}.#{namespace}", subscriber)
43
+ # Adds event subscribers for all new methods added to the class.
44
+ def method_added(event)
45
+ # Only public methods are added as subscribers, and only if a notifier
46
+ # has been set up. This means that subscribers will only be set up for
47
+ # classes that call #attach_to.
48
+ if public_method_defined?(event) && notifier
49
+ add_event_subscriber(event)
40
50
  end
41
51
  end
42
52
 
43
53
  def subscribers
44
54
  @@subscribers ||= []
45
55
  end
56
+
57
+ # TODO Change this to private once we've dropped Ruby 2.2 support.
58
+ # Workaround for Ruby 2.2 "private attribute?" warning.
59
+ protected
60
+
61
+ attr_reader :subscriber, :notifier, :namespace
62
+
63
+ private
64
+
65
+ def add_event_subscriber(event) # :doc:
66
+ return if %w{ start finish }.include?(event.to_s)
67
+
68
+ pattern = "#{event}.#{namespace}"
69
+
70
+ # Don't add multiple subscribers (eg. if methods are redefined).
71
+ return if subscriber.patterns.include?(pattern)
72
+
73
+ subscriber.patterns << pattern
74
+ notifier.subscribe(pattern, subscriber)
75
+ end
46
76
  end
47
77
 
78
+ attr_reader :patterns # :nodoc:
79
+
48
80
  def initialize
49
81
  @queue_key = [self.class.name, object_id].join "-"
82
+ @patterns = []
50
83
  super
51
84
  end
52
85
 
53
86
  def start(name, id, payload)
54
- e = ActiveSupport::Notifications::Event.new(name, Time.now, nil, id, payload)
87
+ e = ActiveSupport::Notifications::Event.new(name, now, nil, id, payload)
55
88
  parent = event_stack.last
56
89
  parent << e if parent
57
90
 
@@ -59,19 +92,23 @@ module ActiveSupport
59
92
  end
60
93
 
61
94
  def finish(name, id, payload)
62
- finished = Time.now
95
+ finished = now
63
96
  event = event_stack.pop
64
97
  event.end = finished
65
98
  event.payload.merge!(payload)
66
99
 
67
- method = name.split('.').first
100
+ method = name.split(".".freeze).first
68
101
  send(method, event)
69
102
  end
70
103
 
71
104
  private
72
105
 
73
106
  def event_stack
74
- SubscriberQueueRegistry.get_queue(@queue_key)
107
+ SubscriberQueueRegistry.instance.get_queue(@queue_key)
108
+ end
109
+
110
+ def now
111
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
75
112
  end
76
113
  end
77
114
 
@@ -1,7 +1,9 @@
1
- require 'active_support/core_ext/module/delegation'
2
- require 'active_support/core_ext/object/blank'
3
- require 'logger'
4
- require 'active_support/logger'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/module/delegation"
4
+ require "active_support/core_ext/object/blank"
5
+ require "logger"
6
+ require "active_support/logger"
5
7
 
6
8
  module ActiveSupport
7
9
  # Wraps any standard Logger object to provide tagging capabilities.
@@ -43,16 +45,17 @@ module ActiveSupport
43
45
  end
44
46
 
45
47
  def current_tags
46
- Thread.current[:activesupport_tagged_logging_tags] ||= []
48
+ # We use our object ID here to avoid conflicting with other instances
49
+ thread_key = @thread_key ||= "activesupport_tagged_logging_tags:#{object_id}".freeze
50
+ Thread.current[thread_key] ||= []
47
51
  end
48
52
 
49
- private
50
- def tags_text
51
- tags = current_tags
52
- if tags.any?
53
- tags.collect { |tag| "[#{tag}] " }.join
54
- end
53
+ def tags_text
54
+ tags = current_tags
55
+ if tags.any?
56
+ tags.collect { |tag| "[#{tag}] " }.join
55
57
  end
58
+ end
56
59
  end
57
60
 
58
61
  def self.new(logger)
@@ -1,42 +1,54 @@
1
- gem 'minitest' # make sure we get the gem, not stdlib
2
- require 'minitest/unit'
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/pending'
8
- require 'active_support/testing/declarative'
9
- require 'active_support/testing/isolation'
10
- require 'active_support/testing/constant_lookup'
11
- require 'active_support/core_ext/kernel/reporting'
12
- require 'active_support/deprecation'
1
+ # frozen_string_literal: true
13
2
 
14
- begin
15
- silence_warnings { require 'mocha/setup' }
16
- rescue LoadError
17
- end
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"
18
14
 
19
15
  module ActiveSupport
20
- class TestCase < ::MiniTest::Unit::TestCase
21
- Assertion = MiniTest::Assertion
22
- alias_method :method_name, :__name__
16
+ class TestCase < ::Minitest::Test
17
+ Assertion = Minitest::Assertion
23
18
 
24
- $tags = {}
25
- def self.for_tag(tag)
26
- yield if $tags[tag]
27
- end
19
+ class << self
20
+ # Sets the order in which test cases are run.
21
+ #
22
+ # ActiveSupport::TestCase.test_order = :random # => :random
23
+ #
24
+ # Valid values are:
25
+ # * +:random+ (to run tests in random order)
26
+ # * +:parallel+ (to run tests in parallel)
27
+ # * +:sorted+ (to run tests alphabetically by method name)
28
+ # * +:alpha+ (equivalent to +:sorted+)
29
+ def test_order=(new_order)
30
+ ActiveSupport.test_order = new_order
31
+ end
28
32
 
29
- # FIXME: we have tests that depend on run order, we should fix that and
30
- # remove this method.
31
- def self.test_order # :nodoc:
32
- :sorted
33
+ # Returns the order in which test cases are run.
34
+ #
35
+ # ActiveSupport::TestCase.test_order # => :random
36
+ #
37
+ # Possible values are +:random+, +:parallel+, +:alpha+, +:sorted+.
38
+ # Defaults to +:random+.
39
+ def test_order
40
+ ActiveSupport.test_order ||= :random
41
+ end
33
42
  end
34
43
 
44
+ alias_method :method_name, :name
45
+
35
46
  include ActiveSupport::Testing::TaggedLogging
36
- include ActiveSupport::Testing::SetupAndTeardown
47
+ prepend ActiveSupport::Testing::SetupAndTeardown
37
48
  include ActiveSupport::Testing::Assertions
38
49
  include ActiveSupport::Testing::Deprecation
39
- include ActiveSupport::Testing::Pending
50
+ include ActiveSupport::Testing::TimeHelpers
51
+ include ActiveSupport::Testing::FileFixtures
40
52
  extend ActiveSupport::Testing::Declarative
41
53
 
42
54
  # test/unit backwards compatibility methods
@@ -55,13 +67,6 @@ module ActiveSupport
55
67
  alias :assert_not_respond_to :refute_respond_to
56
68
  alias :assert_not_same :refute_same
57
69
 
58
- # Fails if the block raises an exception.
59
- #
60
- # assert_nothing_raised do
61
- # ...
62
- # end
63
- def assert_nothing_raised(*args)
64
- yield
65
- end
70
+ ActiveSupport.run_load_hooks(:active_support_test_case, self)
66
71
  end
67
72
  end
@@ -1,15 +1,17 @@
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
  #
10
12
  # assert_not nil # => true
11
13
  # assert_not false # => true
12
- # assert_not 'foo' # => 'foo' is not nil or false
14
+ # assert_not 'foo' # => Expected "foo" to be nil or false
13
15
  #
14
16
  # An error message can be specified.
15
17
  #
@@ -19,108 +21,193 @@ 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
95
124
 
96
- # Test if an expression is blank. Passes if <tt>object.blank?</tt>
97
- # is +true+.
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.
98
141
  #
99
- # assert_blank [] # => true
100
- # assert_blank [[]] # => [[]] is not blank
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
101
153
  #
102
154
  # An error message can be specified.
103
155
  #
104
- # assert_blank [], 'this should be blank'
105
- def assert_blank(object, message=nil)
106
- ActiveSupport::Deprecation.warn('"assert_blank" is deprecated. Please use "assert object.blank?" instead')
107
- message ||= "#{object.inspect} is not blank"
108
- assert object.blank?, message
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
109
185
  end
110
186
 
111
- # Test if an expression is not blank. Passes if <tt>object.present?</tt>
112
- # is +true+.
187
+ # Assertion that the result of evaluating an expression is not changed before
188
+ # and after invoking the passed in block.
113
189
  #
114
- # assert_present({ data: 'x' }) # => true
115
- # assert_present({}) # => {} is blank
190
+ # assert_no_changes 'Status.all_good?' do
191
+ # post :create, params: { status: { ok: true } }
192
+ # end
116
193
  #
117
194
  # An error message can be specified.
118
195
  #
119
- # assert_present({ data: 'x' }, 'this should not be blank')
120
- def assert_present(object, message=nil)
121
- ActiveSupport::Deprecation.warn('"assert_present" is deprecated. Please use "assert object.present?" instead')
122
- message ||= "#{object.inspect} is blank"
123
- assert object.present?, message
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
124
211
  end
125
212
  end
126
213
  end
@@ -1,5 +1,7 @@
1
- gem 'minitest'
1
+ # frozen_string_literal: true
2
2
 
3
- require 'minitest/unit'
3
+ gem "minitest"
4
4
 
5
- MiniTest::Unit.autorun
5
+ require "minitest"
6
+
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
 
@@ -36,19 +38,14 @@ module ActiveSupport
36
38
  while names.size > 0 do
37
39
  names.last.sub!(/Test$/, "")
38
40
  begin
39
- constant = names.join("::").constantize
41
+ constant = names.join("::").safe_constantize
40
42
  break(constant) if yield(constant)
41
- rescue NoMethodError # subclass of NameError
42
- raise
43
- rescue NameError
44
- # Constant wasn't found, move on
45
43
  ensure
46
44
  names.pop
47
45
  end
48
46
  end
49
47
  end
50
48
  end
51
-
52
49
  end
53
50
  end
54
51
  end
@@ -1,30 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  module Testing
3
5
  module Declarative
4
-
5
- def self.extended(klass) #:nodoc:
6
- klass.class_eval do
7
-
8
- unless method_defined?(:describe)
9
- def self.describe(text)
10
- class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
11
- def self.name
12
- "#{text}"
13
- end
14
- RUBY_EVAL
15
- end
16
- end
17
-
18
- end
19
- end
20
-
21
6
  unless defined?(Spec)
22
- # test "verify something" do
23
- # ...
24
- # end
7
+ # Helper to define a test method using a String. Under the hood, it replaces
8
+ # spaces with underscores and defines the test method.
9
+ #
10
+ # test "verify something" do
11
+ # ...
12
+ # end
25
13
  def test(name, &block)
26
- test_name = "test_#{name.gsub(/\s+/,'_')}".to_sym
27
- defined = instance_method(test_name) rescue false
14
+ test_name = "test_#{name.gsub(/\s+/, '_')}".to_sym
15
+ defined = method_defined? test_name
28
16
  raise "#{test_name} is already defined in #{self}" if defined
29
17
  if block_given?
30
18
  define_method(test_name, &block)
@@ -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