activesupport 6.0.0

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 (250) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +572 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +40 -0
  5. data/lib/active_support.rb +96 -0
  6. data/lib/active_support/actionable_error.rb +48 -0
  7. data/lib/active_support/all.rb +5 -0
  8. data/lib/active_support/array_inquirer.rb +48 -0
  9. data/lib/active_support/backtrace_cleaner.rb +132 -0
  10. data/lib/active_support/benchmarkable.rb +51 -0
  11. data/lib/active_support/builder.rb +8 -0
  12. data/lib/active_support/cache.rb +830 -0
  13. data/lib/active_support/cache/file_store.rb +196 -0
  14. data/lib/active_support/cache/mem_cache_store.rb +212 -0
  15. data/lib/active_support/cache/memory_store.rb +174 -0
  16. data/lib/active_support/cache/null_store.rb +48 -0
  17. data/lib/active_support/cache/redis_cache_store.rb +488 -0
  18. data/lib/active_support/cache/strategy/local_cache.rb +194 -0
  19. data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
  20. data/lib/active_support/callbacks.rb +856 -0
  21. data/lib/active_support/concern.rb +171 -0
  22. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +17 -0
  23. data/lib/active_support/concurrency/share_lock.rb +227 -0
  24. data/lib/active_support/configurable.rb +146 -0
  25. data/lib/active_support/core_ext.rb +5 -0
  26. data/lib/active_support/core_ext/array.rb +9 -0
  27. data/lib/active_support/core_ext/array/access.rb +104 -0
  28. data/lib/active_support/core_ext/array/conversions.rb +213 -0
  29. data/lib/active_support/core_ext/array/extract.rb +21 -0
  30. data/lib/active_support/core_ext/array/extract_options.rb +31 -0
  31. data/lib/active_support/core_ext/array/grouping.rb +109 -0
  32. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  33. data/lib/active_support/core_ext/array/prepend_and_append.rb +5 -0
  34. data/lib/active_support/core_ext/array/wrap.rb +48 -0
  35. data/lib/active_support/core_ext/benchmark.rb +16 -0
  36. data/lib/active_support/core_ext/big_decimal.rb +3 -0
  37. data/lib/active_support/core_ext/big_decimal/conversions.rb +14 -0
  38. data/lib/active_support/core_ext/class.rb +4 -0
  39. data/lib/active_support/core_ext/class/attribute.rb +141 -0
  40. data/lib/active_support/core_ext/class/attribute_accessors.rb +6 -0
  41. data/lib/active_support/core_ext/class/subclasses.rb +54 -0
  42. data/lib/active_support/core_ext/date.rb +7 -0
  43. data/lib/active_support/core_ext/date/acts_like.rb +10 -0
  44. data/lib/active_support/core_ext/date/blank.rb +14 -0
  45. data/lib/active_support/core_ext/date/calculations.rb +146 -0
  46. data/lib/active_support/core_ext/date/conversions.rb +96 -0
  47. data/lib/active_support/core_ext/date/zones.rb +8 -0
  48. data/lib/active_support/core_ext/date_and_time/calculations.rb +351 -0
  49. data/lib/active_support/core_ext/date_and_time/compatibility.rb +16 -0
  50. data/lib/active_support/core_ext/date_and_time/zones.rb +41 -0
  51. data/lib/active_support/core_ext/date_time.rb +7 -0
  52. data/lib/active_support/core_ext/date_time/acts_like.rb +16 -0
  53. data/lib/active_support/core_ext/date_time/blank.rb +14 -0
  54. data/lib/active_support/core_ext/date_time/calculations.rb +211 -0
  55. data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
  56. data/lib/active_support/core_ext/date_time/conversions.rb +107 -0
  57. data/lib/active_support/core_ext/digest.rb +3 -0
  58. data/lib/active_support/core_ext/digest/uuid.rb +53 -0
  59. data/lib/active_support/core_ext/enumerable.rb +188 -0
  60. data/lib/active_support/core_ext/file.rb +3 -0
  61. data/lib/active_support/core_ext/file/atomic.rb +70 -0
  62. data/lib/active_support/core_ext/hash.rb +10 -0
  63. data/lib/active_support/core_ext/hash/compact.rb +5 -0
  64. data/lib/active_support/core_ext/hash/conversions.rb +263 -0
  65. data/lib/active_support/core_ext/hash/deep_merge.rb +34 -0
  66. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  67. data/lib/active_support/core_ext/hash/except.rb +24 -0
  68. data/lib/active_support/core_ext/hash/indifferent_access.rb +24 -0
  69. data/lib/active_support/core_ext/hash/keys.rb +143 -0
  70. data/lib/active_support/core_ext/hash/reverse_merge.rb +25 -0
  71. data/lib/active_support/core_ext/hash/slice.rb +26 -0
  72. data/lib/active_support/core_ext/hash/transform_values.rb +5 -0
  73. data/lib/active_support/core_ext/integer.rb +5 -0
  74. data/lib/active_support/core_ext/integer/inflections.rb +31 -0
  75. data/lib/active_support/core_ext/integer/multiple.rb +12 -0
  76. data/lib/active_support/core_ext/integer/time.rb +22 -0
  77. data/lib/active_support/core_ext/kernel.rb +5 -0
  78. data/lib/active_support/core_ext/kernel/concern.rb +14 -0
  79. data/lib/active_support/core_ext/kernel/reporting.rb +45 -0
  80. data/lib/active_support/core_ext/kernel/singleton_class.rb +8 -0
  81. data/lib/active_support/core_ext/load_error.rb +9 -0
  82. data/lib/active_support/core_ext/marshal.rb +24 -0
  83. data/lib/active_support/core_ext/module.rb +13 -0
  84. data/lib/active_support/core_ext/module/aliasing.rb +31 -0
  85. data/lib/active_support/core_ext/module/anonymous.rb +30 -0
  86. data/lib/active_support/core_ext/module/attr_internal.rb +38 -0
  87. data/lib/active_support/core_ext/module/attribute_accessors.rb +212 -0
  88. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +144 -0
  89. data/lib/active_support/core_ext/module/concerning.rb +134 -0
  90. data/lib/active_support/core_ext/module/delegation.rb +313 -0
  91. data/lib/active_support/core_ext/module/deprecation.rb +25 -0
  92. data/lib/active_support/core_ext/module/introspection.rb +86 -0
  93. data/lib/active_support/core_ext/module/reachable.rb +6 -0
  94. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  95. data/lib/active_support/core_ext/module/remove_method.rb +17 -0
  96. data/lib/active_support/core_ext/name_error.rb +38 -0
  97. data/lib/active_support/core_ext/numeric.rb +5 -0
  98. data/lib/active_support/core_ext/numeric/bytes.rb +66 -0
  99. data/lib/active_support/core_ext/numeric/conversions.rb +136 -0
  100. data/lib/active_support/core_ext/numeric/inquiry.rb +5 -0
  101. data/lib/active_support/core_ext/numeric/time.rb +66 -0
  102. data/lib/active_support/core_ext/object.rb +16 -0
  103. data/lib/active_support/core_ext/object/acts_like.rb +21 -0
  104. data/lib/active_support/core_ext/object/blank.rb +155 -0
  105. data/lib/active_support/core_ext/object/conversions.rb +6 -0
  106. data/lib/active_support/core_ext/object/deep_dup.rb +55 -0
  107. data/lib/active_support/core_ext/object/duplicable.rb +49 -0
  108. data/lib/active_support/core_ext/object/inclusion.rb +29 -0
  109. data/lib/active_support/core_ext/object/instance_variables.rb +30 -0
  110. data/lib/active_support/core_ext/object/json.rb +228 -0
  111. data/lib/active_support/core_ext/object/to_param.rb +3 -0
  112. data/lib/active_support/core_ext/object/to_query.rb +89 -0
  113. data/lib/active_support/core_ext/object/try.rb +156 -0
  114. data/lib/active_support/core_ext/object/with_options.rb +82 -0
  115. data/lib/active_support/core_ext/range.rb +7 -0
  116. data/lib/active_support/core_ext/range/compare_range.rb +70 -0
  117. data/lib/active_support/core_ext/range/conversions.rb +41 -0
  118. data/lib/active_support/core_ext/range/each.rb +25 -0
  119. data/lib/active_support/core_ext/range/include_range.rb +9 -0
  120. data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
  121. data/lib/active_support/core_ext/range/overlaps.rb +10 -0
  122. data/lib/active_support/core_ext/regexp.rb +7 -0
  123. data/lib/active_support/core_ext/securerandom.rb +45 -0
  124. data/lib/active_support/core_ext/string.rb +15 -0
  125. data/lib/active_support/core_ext/string/access.rb +114 -0
  126. data/lib/active_support/core_ext/string/behavior.rb +8 -0
  127. data/lib/active_support/core_ext/string/conversions.rb +59 -0
  128. data/lib/active_support/core_ext/string/exclude.rb +13 -0
  129. data/lib/active_support/core_ext/string/filters.rb +145 -0
  130. data/lib/active_support/core_ext/string/indent.rb +45 -0
  131. data/lib/active_support/core_ext/string/inflections.rb +259 -0
  132. data/lib/active_support/core_ext/string/inquiry.rb +15 -0
  133. data/lib/active_support/core_ext/string/multibyte.rb +58 -0
  134. data/lib/active_support/core_ext/string/output_safety.rb +314 -0
  135. data/lib/active_support/core_ext/string/starts_ends_with.rb +6 -0
  136. data/lib/active_support/core_ext/string/strip.rb +27 -0
  137. data/lib/active_support/core_ext/string/zones.rb +16 -0
  138. data/lib/active_support/core_ext/time.rb +7 -0
  139. data/lib/active_support/core_ext/time/acts_like.rb +10 -0
  140. data/lib/active_support/core_ext/time/calculations.rb +344 -0
  141. data/lib/active_support/core_ext/time/compatibility.rb +16 -0
  142. data/lib/active_support/core_ext/time/conversions.rb +72 -0
  143. data/lib/active_support/core_ext/time/zones.rb +113 -0
  144. data/lib/active_support/core_ext/uri.rb +25 -0
  145. data/lib/active_support/current_attributes.rb +203 -0
  146. data/lib/active_support/dependencies.rb +806 -0
  147. data/lib/active_support/dependencies/autoload.rb +79 -0
  148. data/lib/active_support/dependencies/interlock.rb +57 -0
  149. data/lib/active_support/dependencies/zeitwerk_integration.rb +110 -0
  150. data/lib/active_support/deprecation.rb +46 -0
  151. data/lib/active_support/deprecation/behaviors.rb +109 -0
  152. data/lib/active_support/deprecation/constant_accessor.rb +52 -0
  153. data/lib/active_support/deprecation/instance_delegator.rb +39 -0
  154. data/lib/active_support/deprecation/method_wrappers.rb +78 -0
  155. data/lib/active_support/deprecation/proxy_wrappers.rb +173 -0
  156. data/lib/active_support/deprecation/reporting.rb +114 -0
  157. data/lib/active_support/descendants_tracker.rb +109 -0
  158. data/lib/active_support/digest.rb +20 -0
  159. data/lib/active_support/duration.rb +433 -0
  160. data/lib/active_support/duration/iso8601_parser.rb +124 -0
  161. data/lib/active_support/duration/iso8601_serializer.rb +54 -0
  162. data/lib/active_support/encrypted_configuration.rb +45 -0
  163. data/lib/active_support/encrypted_file.rb +100 -0
  164. data/lib/active_support/evented_file_update_checker.rb +235 -0
  165. data/lib/active_support/execution_wrapper.rb +129 -0
  166. data/lib/active_support/executor.rb +8 -0
  167. data/lib/active_support/file_update_checker.rb +163 -0
  168. data/lib/active_support/gem_version.rb +17 -0
  169. data/lib/active_support/gzip.rb +38 -0
  170. data/lib/active_support/hash_with_indifferent_access.rb +399 -0
  171. data/lib/active_support/i18n.rb +16 -0
  172. data/lib/active_support/i18n_railtie.rb +126 -0
  173. data/lib/active_support/inflections.rb +72 -0
  174. data/lib/active_support/inflector.rb +9 -0
  175. data/lib/active_support/inflector/inflections.rb +257 -0
  176. data/lib/active_support/inflector/methods.rb +398 -0
  177. data/lib/active_support/inflector/transliterate.rb +147 -0
  178. data/lib/active_support/json.rb +4 -0
  179. data/lib/active_support/json/decoding.rb +76 -0
  180. data/lib/active_support/json/encoding.rb +134 -0
  181. data/lib/active_support/key_generator.rb +41 -0
  182. data/lib/active_support/lazy_load_hooks.rb +82 -0
  183. data/lib/active_support/locale/en.rb +31 -0
  184. data/lib/active_support/locale/en.yml +135 -0
  185. data/lib/active_support/log_subscriber.rb +135 -0
  186. data/lib/active_support/log_subscriber/test_helper.rb +106 -0
  187. data/lib/active_support/logger.rb +93 -0
  188. data/lib/active_support/logger_silence.rb +45 -0
  189. data/lib/active_support/logger_thread_safe_level.rb +56 -0
  190. data/lib/active_support/message_encryptor.rb +227 -0
  191. data/lib/active_support/message_verifier.rb +205 -0
  192. data/lib/active_support/messages/metadata.rb +71 -0
  193. data/lib/active_support/messages/rotation_configuration.rb +22 -0
  194. data/lib/active_support/messages/rotator.rb +56 -0
  195. data/lib/active_support/multibyte.rb +23 -0
  196. data/lib/active_support/multibyte/chars.rb +216 -0
  197. data/lib/active_support/multibyte/unicode.rb +157 -0
  198. data/lib/active_support/notifications.rb +253 -0
  199. data/lib/active_support/notifications/fanout.rb +244 -0
  200. data/lib/active_support/notifications/instrumenter.rb +164 -0
  201. data/lib/active_support/number_helper.rb +378 -0
  202. data/lib/active_support/number_helper/number_converter.rb +184 -0
  203. data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
  204. data/lib/active_support/number_helper/number_to_delimited_converter.rb +31 -0
  205. data/lib/active_support/number_helper/number_to_human_converter.rb +70 -0
  206. data/lib/active_support/number_helper/number_to_human_size_converter.rb +61 -0
  207. data/lib/active_support/number_helper/number_to_percentage_converter.rb +16 -0
  208. data/lib/active_support/number_helper/number_to_phone_converter.rb +60 -0
  209. data/lib/active_support/number_helper/number_to_rounded_converter.rb +56 -0
  210. data/lib/active_support/number_helper/rounding_helper.rb +66 -0
  211. data/lib/active_support/option_merger.rb +27 -0
  212. data/lib/active_support/ordered_hash.rb +50 -0
  213. data/lib/active_support/ordered_options.rb +85 -0
  214. data/lib/active_support/parameter_filter.rb +129 -0
  215. data/lib/active_support/per_thread_registry.rb +60 -0
  216. data/lib/active_support/proxy_object.rb +15 -0
  217. data/lib/active_support/rails.rb +29 -0
  218. data/lib/active_support/railtie.rb +80 -0
  219. data/lib/active_support/reloader.rb +130 -0
  220. data/lib/active_support/rescuable.rb +174 -0
  221. data/lib/active_support/security_utils.rb +31 -0
  222. data/lib/active_support/string_inquirer.rb +34 -0
  223. data/lib/active_support/subscriber.rb +169 -0
  224. data/lib/active_support/tagged_logging.rb +88 -0
  225. data/lib/active_support/test_case.rb +163 -0
  226. data/lib/active_support/testing/assertions.rb +228 -0
  227. data/lib/active_support/testing/autorun.rb +7 -0
  228. data/lib/active_support/testing/constant_lookup.rb +51 -0
  229. data/lib/active_support/testing/declarative.rb +28 -0
  230. data/lib/active_support/testing/deprecation.rb +38 -0
  231. data/lib/active_support/testing/file_fixtures.rb +38 -0
  232. data/lib/active_support/testing/isolation.rb +110 -0
  233. data/lib/active_support/testing/method_call_assertions.rb +70 -0
  234. data/lib/active_support/testing/parallelization.rb +128 -0
  235. data/lib/active_support/testing/setup_and_teardown.rb +55 -0
  236. data/lib/active_support/testing/stream.rb +44 -0
  237. data/lib/active_support/testing/tagged_logging.rb +27 -0
  238. data/lib/active_support/testing/time_helpers.rb +200 -0
  239. data/lib/active_support/time.rb +20 -0
  240. data/lib/active_support/time_with_zone.rb +561 -0
  241. data/lib/active_support/values/time_zone.rb +570 -0
  242. data/lib/active_support/version.rb +10 -0
  243. data/lib/active_support/xml_mini.rb +202 -0
  244. data/lib/active_support/xml_mini/jdom.rb +183 -0
  245. data/lib/active_support/xml_mini/libxml.rb +80 -0
  246. data/lib/active_support/xml_mini/libxmlsax.rb +83 -0
  247. data/lib/active_support/xml_mini/nokogiri.rb +83 -0
  248. data/lib/active_support/xml_mini/nokogirisax.rb +86 -0
  249. data/lib/active_support/xml_mini/rexml.rb +130 -0
  250. metadata +385 -0
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ # Wrapping a string in this class gives you a prettier way to test
5
+ # for equality. The value returned by <tt>Rails.env</tt> is wrapped
6
+ # in a StringInquirer object, so instead of calling this:
7
+ #
8
+ # Rails.env == 'production'
9
+ #
10
+ # you can call this:
11
+ #
12
+ # Rails.env.production?
13
+ #
14
+ # == Instantiating a new StringInquirer
15
+ #
16
+ # vehicle = ActiveSupport::StringInquirer.new('car')
17
+ # vehicle.car? # => true
18
+ # vehicle.bike? # => false
19
+ class StringInquirer < String
20
+ private
21
+
22
+ def respond_to_missing?(method_name, include_private = false)
23
+ (method_name[-1] == "?") || super
24
+ end
25
+
26
+ def method_missing(method_name, *arguments)
27
+ if method_name[-1] == "?"
28
+ self == method_name[0..-2]
29
+ else
30
+ super
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,169 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/per_thread_registry"
4
+ require "active_support/notifications"
5
+
6
+ module ActiveSupport
7
+ # ActiveSupport::Subscriber is an object set to consume
8
+ # ActiveSupport::Notifications. The subscriber dispatches notifications to
9
+ # a registered object based on its given namespace.
10
+ #
11
+ # An example would be an Active Record subscriber responsible for collecting
12
+ # statistics about queries:
13
+ #
14
+ # module ActiveRecord
15
+ # class StatsSubscriber < ActiveSupport::Subscriber
16
+ # attach_to :active_record
17
+ #
18
+ # def sql(event)
19
+ # Statsd.timing("sql.#{event.payload[:name]}", event.duration)
20
+ # end
21
+ # end
22
+ # end
23
+ #
24
+ # After configured, whenever a "sql.active_record" notification is published,
25
+ # it will properly dispatch the event (ActiveSupport::Notifications::Event) to
26
+ # the +sql+ method.
27
+ #
28
+ # We can detach a subscriber as well:
29
+ #
30
+ # ActiveRecord::StatsSubscriber.detach_from(:active_record)
31
+ class Subscriber
32
+ class << self
33
+ # Attach the subscriber to a namespace.
34
+ def attach_to(namespace, subscriber = new, notifier = ActiveSupport::Notifications)
35
+ @namespace = namespace
36
+ @subscriber = subscriber
37
+ @notifier = notifier
38
+
39
+ subscribers << subscriber
40
+
41
+ # Add event subscribers for all existing methods on the class.
42
+ subscriber.public_methods(false).each do |event|
43
+ add_event_subscriber(event)
44
+ end
45
+ end
46
+
47
+ # Detach the subscriber from a namespace.
48
+ def detach_from(namespace, notifier = ActiveSupport::Notifications)
49
+ @namespace = namespace
50
+ @subscriber = find_attached_subscriber
51
+ @notifier = notifier
52
+
53
+ return unless subscriber
54
+
55
+ subscribers.delete(subscriber)
56
+
57
+ # Remove event subscribers of all existing methods on the class.
58
+ subscriber.public_methods(false).each do |event|
59
+ remove_event_subscriber(event)
60
+ end
61
+
62
+ # Reset notifier so that event subscribers will not add for new methods added to the class.
63
+ @notifier = nil
64
+ end
65
+
66
+ # Adds event subscribers for all new methods added to the class.
67
+ def method_added(event)
68
+ # Only public methods are added as subscribers, and only if a notifier
69
+ # has been set up. This means that subscribers will only be set up for
70
+ # classes that call #attach_to.
71
+ if public_method_defined?(event) && notifier
72
+ add_event_subscriber(event)
73
+ end
74
+ end
75
+
76
+ def subscribers
77
+ @@subscribers ||= []
78
+ end
79
+
80
+ private
81
+ attr_reader :subscriber, :notifier, :namespace
82
+
83
+ def add_event_subscriber(event) # :doc:
84
+ return if invalid_event?(event.to_s)
85
+
86
+ pattern = prepare_pattern(event)
87
+
88
+ # Don't add multiple subscribers (eg. if methods are redefined).
89
+ return if pattern_subscribed?(pattern)
90
+
91
+ subscriber.patterns[pattern] = notifier.subscribe(pattern, subscriber)
92
+ end
93
+
94
+ def remove_event_subscriber(event) # :doc:
95
+ return if invalid_event?(event.to_s)
96
+
97
+ pattern = prepare_pattern(event)
98
+
99
+ return unless pattern_subscribed?(pattern)
100
+
101
+ notifier.unsubscribe(subscriber.patterns[pattern])
102
+ subscriber.patterns.delete(pattern)
103
+ end
104
+
105
+ def find_attached_subscriber
106
+ subscribers.find { |attached_subscriber| attached_subscriber.instance_of?(self) }
107
+ end
108
+
109
+ def invalid_event?(event)
110
+ %w{ start finish }.include?(event.to_s)
111
+ end
112
+
113
+ def prepare_pattern(event)
114
+ "#{event}.#{namespace}"
115
+ end
116
+
117
+ def pattern_subscribed?(pattern)
118
+ subscriber.patterns.key?(pattern)
119
+ end
120
+ end
121
+
122
+ attr_reader :patterns # :nodoc:
123
+
124
+ def initialize
125
+ @queue_key = [self.class.name, object_id].join "-"
126
+ @patterns = {}
127
+ super
128
+ end
129
+
130
+ def start(name, id, payload)
131
+ event = ActiveSupport::Notifications::Event.new(name, nil, nil, id, payload)
132
+ event.start!
133
+ parent = event_stack.last
134
+ parent << event if parent
135
+
136
+ event_stack.push event
137
+ end
138
+
139
+ def finish(name, id, payload)
140
+ event = event_stack.pop
141
+ event.finish!
142
+ event.payload.merge!(payload)
143
+
144
+ method = name.split(".").first
145
+ send(method, event)
146
+ end
147
+
148
+ private
149
+ def event_stack
150
+ SubscriberQueueRegistry.instance.get_queue(@queue_key)
151
+ end
152
+ end
153
+
154
+ # This is a registry for all the event stacks kept for subscribers.
155
+ #
156
+ # See the documentation of <tt>ActiveSupport::PerThreadRegistry</tt>
157
+ # for further details.
158
+ class SubscriberQueueRegistry # :nodoc:
159
+ extend PerThreadRegistry
160
+
161
+ def initialize
162
+ @registry = {}
163
+ end
164
+
165
+ def get_queue(queue_key)
166
+ @registry[queue_key] ||= []
167
+ end
168
+ end
169
+ end
@@ -0,0 +1,88 @@
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"
7
+
8
+ module ActiveSupport
9
+ # Wraps any standard Logger object to provide tagging capabilities.
10
+ #
11
+ # logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
12
+ # logger.tagged('BCX') { logger.info 'Stuff' } # Logs "[BCX] Stuff"
13
+ # logger.tagged('BCX', "Jason") { logger.info 'Stuff' } # Logs "[BCX] [Jason] Stuff"
14
+ # logger.tagged('BCX') { logger.tagged('Jason') { logger.info 'Stuff' } } # Logs "[BCX] [Jason] Stuff"
15
+ #
16
+ # This is used by the default Rails.logger as configured by Railties to make
17
+ # it easy to stamp log lines with subdomains, request ids, and anything else
18
+ # to aid debugging of multi-user production applications.
19
+ module TaggedLogging
20
+ module Formatter # :nodoc:
21
+ # This method is invoked when a log event occurs.
22
+ def call(severity, timestamp, progname, msg)
23
+ super(severity, timestamp, progname, "#{tags_text}#{msg}")
24
+ end
25
+
26
+ def tagged(*tags)
27
+ new_tags = push_tags(*tags)
28
+ yield self
29
+ ensure
30
+ pop_tags(new_tags.size)
31
+ end
32
+
33
+ def push_tags(*tags)
34
+ tags.flatten.reject(&:blank?).tap do |new_tags|
35
+ current_tags.concat new_tags
36
+ end
37
+ end
38
+
39
+ def pop_tags(size = 1)
40
+ current_tags.pop size
41
+ end
42
+
43
+ def clear_tags!
44
+ current_tags.clear
45
+ end
46
+
47
+ def current_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}"
50
+ Thread.current[thread_key] ||= []
51
+ end
52
+
53
+ def tags_text
54
+ tags = current_tags
55
+ if tags.one?
56
+ "[#{tags[0]}] "
57
+ elsif tags.any?
58
+ tags.collect { |tag| "[#{tag}] " }.join
59
+ end
60
+ end
61
+ end
62
+
63
+ def self.new(logger)
64
+ logger = logger.dup
65
+
66
+ if logger.formatter
67
+ logger.formatter = logger.formatter.dup
68
+ else
69
+ # Ensure we set a default formatter so we aren't extending nil!
70
+ logger.formatter = ActiveSupport::Logger::SimpleFormatter.new
71
+ end
72
+
73
+ logger.formatter.extend Formatter
74
+ logger.extend(self)
75
+ end
76
+
77
+ delegate :push_tags, :pop_tags, :clear_tags!, to: :formatter
78
+
79
+ def tagged(*tags)
80
+ formatter.tagged(*tags) { yield self }
81
+ end
82
+
83
+ def flush
84
+ clear_tags!
85
+ super if defined?(super)
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,163 @@
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"
16
+
17
+ module ActiveSupport
18
+ class TestCase < ::Minitest::Test
19
+ Assertion = Minitest::Assertion
20
+
21
+ class << self
22
+ # Sets the order in which test cases are run.
23
+ #
24
+ # ActiveSupport::TestCase.test_order = :random # => :random
25
+ #
26
+ # Valid values are:
27
+ # * +:random+ (to run tests in random order)
28
+ # * +:parallel+ (to run tests in parallel)
29
+ # * +:sorted+ (to run tests alphabetically by method name)
30
+ # * +:alpha+ (equivalent to +:sorted+)
31
+ def test_order=(new_order)
32
+ ActiveSupport.test_order = new_order
33
+ end
34
+
35
+ # Returns the order in which test cases are run.
36
+ #
37
+ # ActiveSupport::TestCase.test_order # => :random
38
+ #
39
+ # Possible values are +:random+, +:parallel+, +:alpha+, +:sorted+.
40
+ # Defaults to +:random+.
41
+ def 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."
87
+ end
88
+
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
113
+ end
114
+
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
133
+ end
134
+
135
+ alias_method :method_name, :name
136
+
137
+ include ActiveSupport::Testing::TaggedLogging
138
+ prepend ActiveSupport::Testing::SetupAndTeardown
139
+ include ActiveSupport::Testing::Assertions
140
+ include ActiveSupport::Testing::Deprecation
141
+ include ActiveSupport::Testing::TimeHelpers
142
+ include ActiveSupport::Testing::FileFixtures
143
+ extend ActiveSupport::Testing::Declarative
144
+
145
+ # test/unit backwards compatibility methods
146
+ alias :assert_raise :assert_raises
147
+ alias :assert_not_empty :refute_empty
148
+ alias :assert_not_equal :refute_equal
149
+ alias :assert_not_in_delta :refute_in_delta
150
+ alias :assert_not_in_epsilon :refute_in_epsilon
151
+ alias :assert_not_includes :refute_includes
152
+ alias :assert_not_instance_of :refute_instance_of
153
+ alias :assert_not_kind_of :refute_kind_of
154
+ alias :assert_no_match :refute_match
155
+ alias :assert_not_nil :refute_nil
156
+ alias :assert_not_operator :refute_operator
157
+ alias :assert_not_predicate :refute_predicate
158
+ alias :assert_not_respond_to :refute_respond_to
159
+ alias :assert_not_same :refute_same
160
+
161
+ ActiveSupport.run_load_hooks(:active_support_test_case, self)
162
+ end
163
+ end