activesupport 4.2.8 → 5.2.6

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 +5 -5
  2. data/CHANGELOG.md +424 -373
  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 +91 -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 -17
  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 +29 -16
  50. data/lib/active_support/core_ext/date_time/compatibility.rb +14 -1
  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 +88 -52
  136. data/lib/active_support/core_ext/time/compatibility.rb +12 -1
  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 +314 -38
  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 +5 -3
  165. data/lib/active_support/gzip.rb +7 -5
  166. data/lib/active_support/hash_with_indifferent_access.rb +127 -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 +19 -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 +91 -23
  232. data/lib/active_support/time.rb +14 -12
  233. data/lib/active_support/time_with_zone.rb +182 -40
  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 +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 +11 -9
  243. data/lib/active_support/xml_mini.rb +37 -37
  244. data/lib/active_support.rb +12 -11
  245. metadata +54 -25
  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
@@ -0,0 +1,131 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/execution_wrapper"
4
+
5
+ module ActiveSupport
6
+ #--
7
+ # This class defines several callbacks:
8
+ #
9
+ # to_prepare -- Run once at application startup, and also from
10
+ # +to_run+.
11
+ #
12
+ # to_run -- Run before a work run that is reloading. If
13
+ # +reload_classes_only_on_change+ is true (the default), the class
14
+ # unload will have already occurred.
15
+ #
16
+ # to_complete -- Run after a work run that has reloaded. If
17
+ # +reload_classes_only_on_change+ is false, the class unload will
18
+ # have occurred after the work run, but before this callback.
19
+ #
20
+ # before_class_unload -- Run immediately before the classes are
21
+ # unloaded.
22
+ #
23
+ # after_class_unload -- Run immediately after the classes are
24
+ # unloaded.
25
+ #
26
+ class Reloader < ExecutionWrapper
27
+ define_callbacks :prepare
28
+
29
+ define_callbacks :class_unload
30
+
31
+ # Registers a callback that will run once at application startup and every time the code is reloaded.
32
+ def self.to_prepare(*args, &block)
33
+ set_callback(:prepare, *args, &block)
34
+ end
35
+
36
+ # Registers a callback that will run immediately before the classes are unloaded.
37
+ def self.before_class_unload(*args, &block)
38
+ set_callback(:class_unload, *args, &block)
39
+ end
40
+
41
+ # Registers a callback that will run immediately after the classes are unloaded.
42
+ def self.after_class_unload(*args, &block)
43
+ set_callback(:class_unload, :after, *args, &block)
44
+ end
45
+
46
+ to_run(:after) { self.class.prepare! }
47
+
48
+ # Initiate a manual reload
49
+ def self.reload!
50
+ executor.wrap do
51
+ new.tap do |instance|
52
+ begin
53
+ instance.run!
54
+ ensure
55
+ instance.complete!
56
+ end
57
+ end
58
+ end
59
+ prepare!
60
+ end
61
+
62
+ def self.run! # :nodoc:
63
+ if check!
64
+ super
65
+ else
66
+ Null
67
+ end
68
+ end
69
+
70
+ # Run the supplied block as a work unit, reloading code as needed
71
+ def self.wrap
72
+ executor.wrap do
73
+ super
74
+ end
75
+ end
76
+
77
+ class_attribute :executor, default: Executor
78
+ class_attribute :check, default: lambda { false }
79
+
80
+ def self.check! # :nodoc:
81
+ @should_reload ||= check.call
82
+ end
83
+
84
+ def self.reloaded! # :nodoc:
85
+ @should_reload = false
86
+ end
87
+
88
+ def self.prepare! # :nodoc:
89
+ new.run_callbacks(:prepare)
90
+ end
91
+
92
+ def initialize
93
+ super
94
+ @locked = false
95
+ end
96
+
97
+ # Acquire the ActiveSupport::Dependencies::Interlock unload lock,
98
+ # ensuring it will be released automatically
99
+ def require_unload_lock!
100
+ unless @locked
101
+ ActiveSupport::Dependencies.interlock.start_unloading
102
+ @locked = true
103
+ end
104
+ end
105
+
106
+ # Release the unload lock if it has been previously obtained
107
+ def release_unload_lock!
108
+ if @locked
109
+ @locked = false
110
+ ActiveSupport::Dependencies.interlock.done_unloading
111
+ end
112
+ end
113
+
114
+ def run! # :nodoc:
115
+ super
116
+ release_unload_lock!
117
+ end
118
+
119
+ def class_unload!(&block) # :nodoc:
120
+ require_unload_lock!
121
+ run_callbacks(:class_unload, &block)
122
+ end
123
+
124
+ def complete! # :nodoc:
125
+ super
126
+ self.class.reloaded!
127
+ ensure
128
+ release_unload_lock!
129
+ end
130
+ end
131
+ end
@@ -1,7 +1,8 @@
1
- require 'active_support/concern'
2
- require 'active_support/core_ext/class/attribute'
3
- require 'active_support/core_ext/string/inflections'
4
- require 'active_support/core_ext/array/extract_options'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+ require "active_support/core_ext/class/attribute"
5
+ require "active_support/core_ext/string/inflections"
5
6
 
6
7
  module ActiveSupport
7
8
  # Rescuable module adds support for easier exception handling.
@@ -9,8 +10,7 @@ module ActiveSupport
9
10
  extend Concern
10
11
 
11
12
  included do
12
- class_attribute :rescue_handlers
13
- self.rescue_handlers = []
13
+ class_attribute :rescue_handlers, default: []
14
14
  end
15
15
 
16
16
  module ClassMethods
@@ -37,7 +37,7 @@ module ActiveSupport
37
37
  # render xml: exception, status: 500
38
38
  # end
39
39
  #
40
- # protected
40
+ # private
41
41
  # def deny_access
42
42
  # ...
43
43
  # end
@@ -48,72 +48,127 @@ module ActiveSupport
48
48
  # end
49
49
  #
50
50
  # Exceptions raised inside exception handlers are not propagated up.
51
- def rescue_from(*klasses, &block)
52
- options = klasses.extract_options!
53
-
54
- unless options.has_key?(:with)
51
+ def rescue_from(*klasses, with: nil, &block)
52
+ unless with
55
53
  if block_given?
56
- options[:with] = block
54
+ with = block
57
55
  else
58
- raise ArgumentError, "Need a handler. Supply an options hash that has a :with key as the last argument."
56
+ raise ArgumentError, "Need a handler. Pass the with: keyword argument or provide a block."
59
57
  end
60
58
  end
61
59
 
62
60
  klasses.each do |klass|
63
- key = if klass.is_a?(Class) && klass <= Exception
61
+ key = if klass.is_a?(Module) && klass.respond_to?(:===)
64
62
  klass.name
65
63
  elsif klass.is_a?(String)
66
64
  klass
67
65
  else
68
- raise ArgumentError, "#{klass} is neither an Exception nor a String"
66
+ raise ArgumentError, "#{klass.inspect} must be an Exception class or a String referencing an Exception class"
69
67
  end
70
68
 
71
- # put the new handler at the end because the list is read in reverse
72
- self.rescue_handlers += [[key, options[:with]]]
69
+ # Put the new handler at the end because the list is read in reverse.
70
+ self.rescue_handlers += [[key, with]]
73
71
  end
74
72
  end
75
- end
76
73
 
77
- # Tries to rescue the exception by looking up and calling a registered handler.
78
- def rescue_with_handler(exception)
79
- if handler = handler_for_rescue(exception)
80
- handler.arity != 0 ? handler.call(exception) : handler.call
81
- true # don't rely on the return value of the handler
82
- end
83
- end
74
+ # Matches an exception to a handler based on the exception class.
75
+ #
76
+ # If no handler matches the exception, check for a handler matching the
77
+ # (optional) exception.cause. If no handler matches the exception or its
78
+ # cause, this returns +nil+, so you can deal with unhandled exceptions.
79
+ # Be sure to re-raise unhandled exceptions if this is what you expect.
80
+ #
81
+ # begin
82
+ # …
83
+ # rescue => exception
84
+ # rescue_with_handler(exception) || raise
85
+ # end
86
+ #
87
+ # Returns the exception if it was handled and +nil+ if it was not.
88
+ def rescue_with_handler(exception, object: self, visited_exceptions: [])
89
+ visited_exceptions << exception
84
90
 
85
- def handler_for_rescue(exception)
86
- # We go from right to left because pairs are pushed onto rescue_handlers
87
- # as rescue_from declarations are found.
88
- _, rescuer = self.class.rescue_handlers.reverse.detect do |klass_name, handler|
89
- # The purpose of allowing strings in rescue_from is to support the
90
- # declaration of handler associations for exception classes whose
91
- # definition is yet unknown.
92
- #
93
- # Since this loop needs the constants it would be inconsistent to
94
- # assume they should exist at this point. An early raised exception
95
- # could trigger some other handler and the array could include
96
- # precisely a string whose corresponding constant has not yet been
97
- # seen. This is why we are tolerant to unknown constants.
98
- #
99
- # Note that this tolerance only matters if the exception was given as
100
- # a string, otherwise a NameError will be raised by the interpreter
101
- # itself when rescue_from CONSTANT is executed.
102
- klass = self.class.const_get(klass_name) rescue nil
103
- klass ||= klass_name.constantize rescue nil
104
- exception.is_a?(klass) if klass
91
+ if handler = handler_for_rescue(exception, object: object)
92
+ handler.call exception
93
+ exception
94
+ elsif exception
95
+ if visited_exceptions.include?(exception.cause)
96
+ nil
97
+ else
98
+ rescue_with_handler(exception.cause, object: object, visited_exceptions: visited_exceptions)
99
+ end
100
+ end
105
101
  end
106
102
 
107
- case rescuer
108
- when Symbol
109
- method(rescuer)
110
- when Proc
111
- if rescuer.arity == 0
112
- Proc.new { instance_exec(&rescuer) }
113
- else
114
- Proc.new { |_exception| instance_exec(_exception, &rescuer) }
103
+ def handler_for_rescue(exception, object: self) #:nodoc:
104
+ case rescuer = find_rescue_handler(exception)
105
+ when Symbol
106
+ method = object.method(rescuer)
107
+ if method.arity == 0
108
+ -> e { method.call }
109
+ else
110
+ method
111
+ end
112
+ when Proc
113
+ if rescuer.arity == 0
114
+ -> e { object.instance_exec(&rescuer) }
115
+ else
116
+ -> e { object.instance_exec(e, &rescuer) }
117
+ end
115
118
  end
116
119
  end
120
+
121
+ private
122
+ def find_rescue_handler(exception)
123
+ if exception
124
+ # Handlers are in order of declaration but the most recently declared
125
+ # is the highest priority match, so we search for matching handlers
126
+ # in reverse.
127
+ _, handler = rescue_handlers.reverse_each.detect do |class_or_name, _|
128
+ if klass = constantize_rescue_handler_class(class_or_name)
129
+ klass === exception
130
+ end
131
+ end
132
+
133
+ handler
134
+ end
135
+ end
136
+
137
+ def constantize_rescue_handler_class(class_or_name)
138
+ case class_or_name
139
+ when String, Symbol
140
+ begin
141
+ # Try a lexical lookup first since we support
142
+ #
143
+ # class Super
144
+ # rescue_from 'Error', with: …
145
+ # end
146
+ #
147
+ # class Sub
148
+ # class Error < StandardError; end
149
+ # end
150
+ #
151
+ # so an Error raised in Sub will hit the 'Error' handler.
152
+ const_get class_or_name
153
+ rescue NameError
154
+ class_or_name.safe_constantize
155
+ end
156
+ else
157
+ class_or_name
158
+ end
159
+ end
160
+ end
161
+
162
+ # Delegates to the class method, but uses the instance as the subject for
163
+ # rescue_from handlers (method calls, instance_exec blocks).
164
+ def rescue_with_handler(exception)
165
+ self.class.rescue_with_handler exception, object: self
166
+ end
167
+
168
+ # Internal handler lookup. Delegates to class method. Some libraries call
169
+ # this directly, so keeping it around for compatibility.
170
+ def handler_for_rescue(exception) #:nodoc:
171
+ self.class.handler_for_rescue exception, object: self
117
172
  end
118
173
  end
119
174
  end
@@ -1,15 +1,15 @@
1
- require 'digest'
1
+ # frozen_string_literal: true
2
+
3
+ require "digest/sha2"
2
4
 
3
5
  module ActiveSupport
4
6
  module SecurityUtils
5
- # Constant time string comparison.
7
+ # Constant time string comparison, for fixed length strings.
6
8
  #
7
9
  # The values compared should be of fixed length, such as strings
8
- # that have already been processed by HMAC. This should not be used
9
- # on variable length plaintext strings because it could leak length info
10
- # via timing attacks.
11
- def secure_compare(a, b)
12
- return false unless a.bytesize == b.bytesize
10
+ # that have already been processed by HMAC. Raises in case of length mismatch.
11
+ def fixed_length_secure_compare(a, b)
12
+ raise ArgumentError, "string length mismatch." unless a.bytesize == b.bytesize
13
13
 
14
14
  l = a.unpack "C#{a.bytesize}"
15
15
 
@@ -17,11 +17,15 @@ module ActiveSupport
17
17
  b.each_byte { |byte| res |= byte ^ l.shift }
18
18
  res == 0
19
19
  end
20
- module_function :secure_compare
20
+ module_function :fixed_length_secure_compare
21
21
 
22
- def variable_size_secure_compare(a, b) # :nodoc:
23
- secure_compare(::Digest::SHA256.hexdigest(a), ::Digest::SHA256.hexdigest(b))
22
+ # Constant time string comparison, for variable length strings.
23
+ #
24
+ # The values are first processed by SHA256, so that we don't leak length info
25
+ # via timing attacks.
26
+ def secure_compare(a, b)
27
+ fixed_length_secure_compare(::Digest::SHA256.hexdigest(a), ::Digest::SHA256.hexdigest(b)) && a == b
24
28
  end
25
- module_function :variable_size_secure_compare
29
+ module_function :secure_compare
26
30
  end
27
31
  end
@@ -1,22 +1,30 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  # Wrapping a string in this class gives you a prettier way to test
3
5
  # for equality. The value returned by <tt>Rails.env</tt> is wrapped
4
- # in a StringInquirer object so instead of calling this:
6
+ # in a StringInquirer object, so instead of calling this:
5
7
  #
6
8
  # Rails.env == 'production'
7
9
  #
8
10
  # you can call this:
9
11
  #
10
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
11
19
  class StringInquirer < String
12
20
  private
13
21
 
14
22
  def respond_to_missing?(method_name, include_private = false)
15
- method_name[-1] == '?'
23
+ (method_name[-1] == "?") || super
16
24
  end
17
25
 
18
26
  def method_missing(method_name, *arguments)
19
- if method_name[-1] == '?'
27
+ if method_name[-1] == "?"
20
28
  self == method_name[0..-2]
21
29
  else
22
30
  super
@@ -1,36 +1,33 @@
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)
34
31
  @namespace = namespace
35
32
  @subscriber = subscriber
36
33
  @notifier = notifier
@@ -57,16 +54,20 @@ module ActiveSupport
57
54
  @@subscribers ||= []
58
55
  end
59
56
 
57
+ # TODO Change this to private once we've dropped Ruby 2.2 support.
58
+ # Workaround for Ruby 2.2 "private attribute?" warning.
60
59
  protected
61
60
 
62
61
  attr_reader :subscriber, :notifier, :namespace
63
62
 
64
- def add_event_subscriber(event)
63
+ private
64
+
65
+ def add_event_subscriber(event) # :doc:
65
66
  return if %w{ start finish }.include?(event.to_s)
66
67
 
67
68
  pattern = "#{event}.#{namespace}"
68
69
 
69
- # don't add multiple subscribers (eg. if methods are redefined)
70
+ # Don't add multiple subscribers (eg. if methods are redefined).
70
71
  return if subscriber.patterns.include?(pattern)
71
72
 
72
73
  subscriber.patterns << pattern
@@ -83,7 +84,7 @@ module ActiveSupport
83
84
  end
84
85
 
85
86
  def start(name, id, payload)
86
- e = ActiveSupport::Notifications::Event.new(name, Time.now, nil, id, payload)
87
+ e = ActiveSupport::Notifications::Event.new(name, now, nil, id, payload)
87
88
  parent = event_stack.last
88
89
  parent << e if parent
89
90
 
@@ -91,12 +92,12 @@ module ActiveSupport
91
92
  end
92
93
 
93
94
  def finish(name, id, payload)
94
- finished = Time.now
95
+ finished = now
95
96
  event = event_stack.pop
96
97
  event.end = finished
97
98
  event.payload.merge!(payload)
98
99
 
99
- method = name.split('.').first
100
+ method = name.split(".".freeze).first
100
101
  send(method, event)
101
102
  end
102
103
 
@@ -105,6 +106,10 @@ module ActiveSupport
105
106
  def event_stack
106
107
  SubscriberQueueRegistry.instance.get_queue(@queue_key)
107
108
  end
109
+
110
+ def now
111
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
112
+ end
108
113
  end
109
114
 
110
115
  # This is a registry for all the event stacks kept for subscribers.
@@ -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,15 +1,16 @@
1
- gem 'minitest' # make sure we get the gem, not stdlib
2
- require 'minitest'
3
- require 'active_support/testing/tagged_logging'
4
- require 'active_support/testing/setup_and_teardown'
5
- require 'active_support/testing/assertions'
6
- require 'active_support/testing/deprecation'
7
- require 'active_support/testing/declarative'
8
- require 'active_support/testing/isolation'
9
- require 'active_support/testing/constant_lookup'
10
- require 'active_support/testing/time_helpers'
11
- require 'active_support/core_ext/kernel/reporting'
12
- require 'active_support/deprecation'
1
+ # frozen_string_literal: true
2
+
3
+ gem "minitest" # make sure we get the gem, not stdlib
4
+ require "minitest"
5
+ require "active_support/testing/tagged_logging"
6
+ require "active_support/testing/setup_and_teardown"
7
+ require "active_support/testing/assertions"
8
+ require "active_support/testing/deprecation"
9
+ require "active_support/testing/declarative"
10
+ require "active_support/testing/isolation"
11
+ require "active_support/testing/constant_lookup"
12
+ require "active_support/testing/time_helpers"
13
+ require "active_support/testing/file_fixtures"
13
14
 
14
15
  module ActiveSupport
15
16
  class TestCase < ::Minitest::Test
@@ -31,45 +32,23 @@ module ActiveSupport
31
32
 
32
33
  # Returns the order in which test cases are run.
33
34
  #
34
- # ActiveSupport::TestCase.test_order # => :sorted
35
+ # ActiveSupport::TestCase.test_order # => :random
35
36
  #
36
37
  # Possible values are +:random+, +:parallel+, +:alpha+, +:sorted+.
37
- # Defaults to +:sorted+.
38
+ # Defaults to +:random+.
38
39
  def test_order
39
- test_order = ActiveSupport.test_order
40
-
41
- if test_order.nil?
42
- ActiveSupport::Deprecation.warn "You did not specify a value for the " \
43
- "configuration option `active_support.test_order`. In Rails 5, " \
44
- "the default value of this option will change from `:sorted` to " \
45
- "`:random`.\n" \
46
- "To disable this warning and keep the current behavior, you can add " \
47
- "the following line to your `config/environments/test.rb`:\n" \
48
- "\n" \
49
- " Rails.application.configure do\n" \
50
- " config.active_support.test_order = :sorted\n" \
51
- " end\n" \
52
- "\n" \
53
- "Alternatively, you can opt into the future behavior by setting this " \
54
- "option to `:random`."
55
-
56
- test_order = :sorted
57
- self.test_order = test_order
58
- end
59
-
60
- test_order
40
+ ActiveSupport.test_order ||= :random
61
41
  end
62
-
63
- alias :my_tests_are_order_dependent! :i_suck_and_my_tests_are_order_dependent!
64
42
  end
65
43
 
66
44
  alias_method :method_name, :name
67
45
 
68
46
  include ActiveSupport::Testing::TaggedLogging
69
- include ActiveSupport::Testing::SetupAndTeardown
47
+ prepend ActiveSupport::Testing::SetupAndTeardown
70
48
  include ActiveSupport::Testing::Assertions
71
49
  include ActiveSupport::Testing::Deprecation
72
50
  include ActiveSupport::Testing::TimeHelpers
51
+ include ActiveSupport::Testing::FileFixtures
73
52
  extend ActiveSupport::Testing::Declarative
74
53
 
75
54
  # test/unit backwards compatibility methods
@@ -88,13 +67,6 @@ module ActiveSupport
88
67
  alias :assert_not_respond_to :refute_respond_to
89
68
  alias :assert_not_same :refute_same
90
69
 
91
- # Fails if the block raises an exception.
92
- #
93
- # assert_nothing_raised do
94
- # ...
95
- # end
96
- def assert_nothing_raised(*args)
97
- yield
98
- end
70
+ ActiveSupport.run_load_hooks(:active_support_test_case, self)
99
71
  end
100
72
  end