activesupport 5.1.7 → 6.1.7

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 (262) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +434 -490
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +6 -5
  5. data/lib/active_support/actionable_error.rb +48 -0
  6. data/lib/active_support/all.rb +2 -0
  7. data/lib/active_support/array_inquirer.rb +6 -2
  8. data/lib/active_support/backtrace_cleaner.rb +31 -3
  9. data/lib/active_support/benchmarkable.rb +3 -1
  10. data/lib/active_support/builder.rb +2 -0
  11. data/lib/active_support/cache/file_store.rb +37 -36
  12. data/lib/active_support/cache/mem_cache_store.rb +72 -56
  13. data/lib/active_support/cache/memory_store.rb +61 -33
  14. data/lib/active_support/cache/null_store.rb +10 -3
  15. data/lib/active_support/cache/redis_cache_store.rb +493 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +67 -21
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
  18. data/lib/active_support/cache.rb +310 -126
  19. data/lib/active_support/callbacks.rb +106 -100
  20. data/lib/active_support/concern.rb +79 -6
  21. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
  22. data/lib/active_support/concurrency/share_lock.rb +2 -1
  23. data/lib/active_support/configurable.rb +12 -14
  24. data/lib/active_support/configuration_file.rb +51 -0
  25. data/lib/active_support/core_ext/array/access.rb +21 -7
  26. data/lib/active_support/core_ext/array/conversions.rb +7 -5
  27. data/lib/active_support/core_ext/array/extract.rb +21 -0
  28. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  29. data/lib/active_support/core_ext/array/grouping.rb +2 -0
  30. data/lib/active_support/core_ext/array/inquiry.rb +2 -0
  31. data/lib/active_support/core_ext/array/wrap.rb +2 -0
  32. data/lib/active_support/core_ext/array.rb +3 -1
  33. data/lib/active_support/core_ext/benchmark.rb +4 -2
  34. data/lib/active_support/core_ext/big_decimal/conversions.rb +2 -0
  35. data/lib/active_support/core_ext/big_decimal.rb +2 -0
  36. data/lib/active_support/core_ext/class/attribute.rb +50 -47
  37. data/lib/active_support/core_ext/class/attribute_accessors.rb +2 -0
  38. data/lib/active_support/core_ext/class/subclasses.rb +18 -40
  39. data/lib/active_support/core_ext/class.rb +2 -0
  40. data/lib/active_support/core_ext/date/acts_like.rb +2 -0
  41. data/lib/active_support/core_ext/date/blank.rb +2 -0
  42. data/lib/active_support/core_ext/date/calculations.rb +8 -5
  43. data/lib/active_support/core_ext/date/conversions.rb +12 -10
  44. data/lib/active_support/core_ext/date/zones.rb +2 -0
  45. data/lib/active_support/core_ext/date.rb +2 -0
  46. data/lib/active_support/core_ext/date_and_time/calculations.rb +61 -37
  47. data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -1
  48. data/lib/active_support/core_ext/date_and_time/zones.rb +2 -1
  49. data/lib/active_support/core_ext/date_time/acts_like.rb +2 -0
  50. data/lib/active_support/core_ext/date_time/blank.rb +2 -0
  51. data/lib/active_support/core_ext/date_time/calculations.rb +3 -1
  52. data/lib/active_support/core_ext/date_time/compatibility.rb +7 -5
  53. data/lib/active_support/core_ext/date_time/conversions.rb +2 -1
  54. data/lib/active_support/core_ext/date_time.rb +2 -0
  55. data/lib/active_support/core_ext/digest/uuid.rb +4 -1
  56. data/lib/active_support/core_ext/digest.rb +3 -0
  57. data/lib/active_support/core_ext/enumerable.rb +174 -71
  58. data/lib/active_support/core_ext/file/atomic.rb +3 -1
  59. data/lib/active_support/core_ext/file.rb +2 -0
  60. data/lib/active_support/core_ext/hash/conversions.rb +7 -5
  61. data/lib/active_support/core_ext/hash/deep_merge.rb +8 -12
  62. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  63. data/lib/active_support/core_ext/hash/except.rb +4 -2
  64. data/lib/active_support/core_ext/hash/indifferent_access.rb +2 -0
  65. data/lib/active_support/core_ext/hash/keys.rb +3 -30
  66. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  67. data/lib/active_support/core_ext/hash/slice.rb +8 -29
  68. data/lib/active_support/core_ext/hash.rb +3 -2
  69. data/lib/active_support/core_ext/integer/inflections.rb +2 -0
  70. data/lib/active_support/core_ext/integer/multiple.rb +3 -1
  71. data/lib/active_support/core_ext/integer/time.rb +7 -14
  72. data/lib/active_support/core_ext/integer.rb +2 -0
  73. data/lib/active_support/core_ext/kernel/concern.rb +2 -0
  74. data/lib/active_support/core_ext/kernel/reporting.rb +2 -0
  75. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  76. data/lib/active_support/core_ext/kernel.rb +2 -1
  77. data/lib/active_support/core_ext/load_error.rb +3 -8
  78. data/lib/active_support/core_ext/marshal.rb +4 -0
  79. data/lib/active_support/core_ext/module/aliasing.rb +2 -0
  80. data/lib/active_support/core_ext/module/anonymous.rb +2 -0
  81. data/lib/active_support/core_ext/module/attr_internal.rb +4 -2
  82. data/lib/active_support/core_ext/module/attribute_accessors.rb +44 -56
  83. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +18 -18
  84. data/lib/active_support/core_ext/module/concerning.rb +15 -10
  85. data/lib/active_support/core_ext/module/delegation.rb +103 -58
  86. data/lib/active_support/core_ext/module/deprecation.rb +2 -0
  87. data/lib/active_support/core_ext/module/introspection.rb +18 -15
  88. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  89. data/lib/active_support/core_ext/module/remove_method.rb +5 -23
  90. data/lib/active_support/core_ext/module.rb +3 -1
  91. data/lib/active_support/core_ext/name_error.rb +36 -2
  92. data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
  93. data/lib/active_support/core_ext/numeric/conversions.rb +131 -129
  94. data/lib/active_support/core_ext/numeric/time.rb +7 -15
  95. data/lib/active_support/core_ext/numeric.rb +2 -1
  96. data/lib/active_support/core_ext/object/acts_like.rb +12 -1
  97. data/lib/active_support/core_ext/object/blank.rb +13 -3
  98. data/lib/active_support/core_ext/object/conversions.rb +2 -0
  99. data/lib/active_support/core_ext/object/deep_dup.rb +3 -1
  100. data/lib/active_support/core_ext/object/duplicable.rb +9 -114
  101. data/lib/active_support/core_ext/object/inclusion.rb +2 -0
  102. data/lib/active_support/core_ext/object/instance_variables.rb +2 -0
  103. data/lib/active_support/core_ext/object/json.rb +22 -2
  104. data/lib/active_support/core_ext/object/to_param.rb +2 -0
  105. data/lib/active_support/core_ext/object/to_query.rb +2 -0
  106. data/lib/active_support/core_ext/object/try.rb +19 -7
  107. data/lib/active_support/core_ext/object/with_options.rb +4 -2
  108. data/lib/active_support/core_ext/object.rb +2 -0
  109. data/lib/active_support/core_ext/range/compare_range.rb +82 -0
  110. data/lib/active_support/core_ext/range/conversions.rb +35 -25
  111. data/lib/active_support/core_ext/range/each.rb +5 -2
  112. data/lib/active_support/core_ext/range/include_time_with_zone.rb +28 -0
  113. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  114. data/lib/active_support/core_ext/range.rb +4 -1
  115. data/lib/active_support/core_ext/regexp.rb +10 -5
  116. data/lib/active_support/core_ext/securerandom.rb +25 -3
  117. data/lib/active_support/core_ext/string/access.rb +7 -16
  118. data/lib/active_support/core_ext/string/behavior.rb +2 -0
  119. data/lib/active_support/core_ext/string/conversions.rb +3 -0
  120. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  121. data/lib/active_support/core_ext/string/filters.rb +44 -1
  122. data/lib/active_support/core_ext/string/indent.rb +2 -0
  123. data/lib/active_support/core_ext/string/inflections.rb +69 -16
  124. data/lib/active_support/core_ext/string/inquiry.rb +3 -0
  125. data/lib/active_support/core_ext/string/multibyte.rb +9 -4
  126. data/lib/active_support/core_ext/string/output_safety.rb +104 -20
  127. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
  128. data/lib/active_support/core_ext/string/strip.rb +5 -1
  129. data/lib/active_support/core_ext/string/zones.rb +2 -0
  130. data/lib/active_support/core_ext/string.rb +2 -0
  131. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +14 -0
  132. data/lib/active_support/core_ext/symbol.rb +3 -0
  133. data/lib/active_support/core_ext/time/acts_like.rb +2 -0
  134. data/lib/active_support/core_ext/time/calculations.rb +76 -18
  135. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  136. data/lib/active_support/core_ext/time/conversions.rb +4 -0
  137. data/lib/active_support/core_ext/time/zones.rb +6 -4
  138. data/lib/active_support/core_ext/time.rb +2 -0
  139. data/lib/active_support/core_ext/uri.rb +11 -6
  140. data/lib/active_support/core_ext.rb +3 -1
  141. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  142. data/lib/active_support/current_attributes.rb +210 -0
  143. data/lib/active_support/dependencies/autoload.rb +2 -0
  144. data/lib/active_support/dependencies/interlock.rb +2 -0
  145. data/lib/active_support/dependencies/zeitwerk_integration.rb +120 -0
  146. data/lib/active_support/dependencies.rb +134 -60
  147. data/lib/active_support/deprecation/behaviors.rb +43 -11
  148. data/lib/active_support/deprecation/constant_accessor.rb +4 -2
  149. data/lib/active_support/deprecation/disallowed.rb +56 -0
  150. data/lib/active_support/deprecation/instance_delegator.rb +2 -1
  151. data/lib/active_support/deprecation/method_wrappers.rb +29 -21
  152. data/lib/active_support/deprecation/proxy_wrappers.rb +32 -6
  153. data/lib/active_support/deprecation/reporting.rb +54 -9
  154. data/lib/active_support/deprecation.rb +9 -2
  155. data/lib/active_support/descendants_tracker.rb +61 -9
  156. data/lib/active_support/digest.rb +22 -0
  157. data/lib/active_support/duration/iso8601_parser.rb +6 -6
  158. data/lib/active_support/duration/iso8601_serializer.rb +20 -14
  159. data/lib/active_support/duration.rb +102 -45
  160. data/lib/active_support/encrypted_configuration.rb +45 -0
  161. data/lib/active_support/encrypted_file.rb +117 -0
  162. data/lib/active_support/environment_inquirer.rb +20 -0
  163. data/lib/active_support/evented_file_update_checker.rb +84 -117
  164. data/lib/active_support/execution_wrapper.rb +19 -13
  165. data/lib/active_support/executor.rb +2 -0
  166. data/lib/active_support/file_update_checker.rb +2 -1
  167. data/lib/active_support/fork_tracker.rb +64 -0
  168. data/lib/active_support/gem_version.rb +3 -1
  169. data/lib/active_support/gzip.rb +2 -0
  170. data/lib/active_support/hash_with_indifferent_access.rb +123 -41
  171. data/lib/active_support/i18n.rb +4 -1
  172. data/lib/active_support/i18n_railtie.rb +19 -14
  173. data/lib/active_support/inflections.rb +2 -0
  174. data/lib/active_support/inflector/inflections.rb +19 -8
  175. data/lib/active_support/inflector/methods.rb +87 -77
  176. data/lib/active_support/inflector/transliterate.rb +56 -18
  177. data/lib/active_support/inflector.rb +2 -0
  178. data/lib/active_support/json/decoding.rb +27 -26
  179. data/lib/active_support/json/encoding.rb +13 -3
  180. data/lib/active_support/json.rb +2 -0
  181. data/lib/active_support/key_generator.rb +3 -33
  182. data/lib/active_support/lazy_load_hooks.rb +7 -2
  183. data/lib/active_support/locale/en.rb +33 -0
  184. data/lib/active_support/locale/en.yml +7 -3
  185. data/lib/active_support/log_subscriber/test_helper.rb +2 -0
  186. data/lib/active_support/log_subscriber.rb +42 -11
  187. data/lib/active_support/logger.rb +4 -17
  188. data/lib/active_support/logger_silence.rb +13 -20
  189. data/lib/active_support/logger_thread_safe_level.rb +54 -7
  190. data/lib/active_support/message_encryptor.rb +100 -32
  191. data/lib/active_support/message_verifier.rb +85 -14
  192. data/lib/active_support/messages/metadata.rb +80 -0
  193. data/lib/active_support/messages/rotation_configuration.rb +23 -0
  194. data/lib/active_support/messages/rotator.rb +57 -0
  195. data/lib/active_support/multibyte/chars.rb +12 -68
  196. data/lib/active_support/multibyte/unicode.rb +17 -327
  197. data/lib/active_support/multibyte.rb +2 -0
  198. data/lib/active_support/notifications/fanout.rb +118 -16
  199. data/lib/active_support/notifications/instrumenter.rb +73 -9
  200. data/lib/active_support/notifications.rb +74 -8
  201. data/lib/active_support/number_helper/number_converter.rb +7 -6
  202. data/lib/active_support/number_helper/number_to_currency_converter.rb +6 -9
  203. data/lib/active_support/number_helper/number_to_delimited_converter.rb +5 -2
  204. data/lib/active_support/number_helper/number_to_human_converter.rb +6 -3
  205. data/lib/active_support/number_helper/number_to_human_size_converter.rb +6 -3
  206. data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
  207. data/lib/active_support/number_helper/number_to_phone_converter.rb +5 -2
  208. data/lib/active_support/number_helper/number_to_rounded_converter.rb +14 -27
  209. data/lib/active_support/number_helper/rounding_helper.rb +16 -30
  210. data/lib/active_support/number_helper.rb +40 -12
  211. data/lib/active_support/option_merger.rb +24 -3
  212. data/lib/active_support/ordered_hash.rb +3 -1
  213. data/lib/active_support/ordered_options.rb +17 -5
  214. data/lib/active_support/parameter_filter.rb +133 -0
  215. data/lib/active_support/per_thread_registry.rb +4 -1
  216. data/lib/active_support/proxy_object.rb +2 -0
  217. data/lib/active_support/rails.rb +3 -10
  218. data/lib/active_support/railtie.rb +60 -9
  219. data/lib/active_support/reloader.rb +12 -11
  220. data/lib/active_support/rescuable.rb +7 -6
  221. data/lib/active_support/secure_compare_rotator.rb +51 -0
  222. data/lib/active_support/security_utils.rb +26 -15
  223. data/lib/active_support/string_inquirer.rb +6 -3
  224. data/lib/active_support/subscriber.rb +74 -24
  225. data/lib/active_support/tagged_logging.rb +44 -8
  226. data/lib/active_support/test_case.rb +94 -2
  227. data/lib/active_support/testing/assertions.rb +58 -20
  228. data/lib/active_support/testing/autorun.rb +2 -0
  229. data/lib/active_support/testing/constant_lookup.rb +2 -0
  230. data/lib/active_support/testing/declarative.rb +2 -0
  231. data/lib/active_support/testing/deprecation.rb +2 -1
  232. data/lib/active_support/testing/file_fixtures.rb +4 -0
  233. data/lib/active_support/testing/isolation.rb +4 -2
  234. data/lib/active_support/testing/method_call_assertions.rb +30 -1
  235. data/lib/active_support/testing/parallelization/server.rb +78 -0
  236. data/lib/active_support/testing/parallelization/worker.rb +100 -0
  237. data/lib/active_support/testing/parallelization.rb +51 -0
  238. data/lib/active_support/testing/setup_and_teardown.rb +12 -7
  239. data/lib/active_support/testing/stream.rb +3 -2
  240. data/lib/active_support/testing/tagged_logging.rb +2 -0
  241. data/lib/active_support/testing/time_helpers.rb +78 -13
  242. data/lib/active_support/time.rb +2 -0
  243. data/lib/active_support/time_with_zone.rb +113 -41
  244. data/lib/active_support/values/time_zone.rb +54 -25
  245. data/lib/active_support/version.rb +2 -0
  246. data/lib/active_support/xml_mini/jdom.rb +5 -4
  247. data/lib/active_support/xml_mini/libxml.rb +4 -2
  248. data/lib/active_support/xml_mini/libxmlsax.rb +6 -4
  249. data/lib/active_support/xml_mini/nokogiri.rb +4 -2
  250. data/lib/active_support/xml_mini/nokogirisax.rb +5 -3
  251. data/lib/active_support/xml_mini/rexml.rb +12 -3
  252. data/lib/active_support/xml_mini.rb +5 -11
  253. data/lib/active_support.rb +18 -13
  254. metadata +71 -32
  255. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
  256. data/lib/active_support/core_ext/hash/compact.rb +0 -27
  257. data/lib/active_support/core_ext/hash/transform_values.rb +0 -30
  258. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  259. data/lib/active_support/core_ext/module/reachable.rb +0 -8
  260. data/lib/active_support/core_ext/numeric/inquiry.rb +0 -26
  261. data/lib/active_support/core_ext/range/include_range.rb +0 -23
  262. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  module NumberHelper
3
5
  extend ActiveSupport::Autoload
@@ -69,6 +71,8 @@ module ActiveSupport
69
71
  # (defaults to current locale).
70
72
  # * <tt>:precision</tt> - Sets the level of precision (defaults
71
73
  # to 2).
74
+ # * <tt>:round_mode</tt> - Determine how rounding is performed
75
+ # (defaults to :default. See BigDecimal::mode)
72
76
  # * <tt>:unit</tt> - Sets the denomination of the currency
73
77
  # (defaults to "$").
74
78
  # * <tt>:separator</tt> - Sets the separator between the units
@@ -83,6 +87,9 @@ module ActiveSupport
83
87
  # number given by <tt>:format</tt>). Accepts the same fields
84
88
  # than <tt>:format</tt>, except <tt>%n</tt> is here the
85
89
  # absolute value of the number.
90
+ # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
91
+ # insignificant zeros after the decimal separator (defaults to
92
+ # +false+).
86
93
  #
87
94
  # ==== Examples
88
95
  #
@@ -92,12 +99,20 @@ module ActiveSupport
92
99
  # number_to_currency(1234567890.506, locale: :fr) # => "1 234 567 890,51 €"
93
100
  # number_to_currency('123a456') # => "$123a456"
94
101
  #
102
+ # number_to_currency("123a456", raise: true) # => InvalidNumberError
103
+ #
104
+ # number_to_currency(-0.456789, precision: 0)
105
+ # # => "$0"
95
106
  # number_to_currency(-1234567890.50, negative_format: '(%u%n)')
96
107
  # # => "($1,234,567,890.50)"
97
108
  # number_to_currency(1234567890.50, unit: '&pound;', separator: ',', delimiter: '')
98
109
  # # => "&pound;1234567890,50"
99
110
  # number_to_currency(1234567890.50, unit: '&pound;', separator: ',', delimiter: '', format: '%n %u')
100
111
  # # => "1234567890,50 &pound;"
112
+ # number_to_currency(1234567890.50, strip_insignificant_zeros: true)
113
+ # # => "$1,234,567,890.5"
114
+ # number_to_currency(1234567890.50, precision: 0, round_mode: :up)
115
+ # # => "$1,234,567,891"
101
116
  def number_to_currency(number, options = {})
102
117
  NumberToCurrencyConverter.convert(number, options)
103
118
  end
@@ -111,6 +126,8 @@ module ActiveSupport
111
126
  # (defaults to current locale).
112
127
  # * <tt>:precision</tt> - Sets the precision of the number
113
128
  # (defaults to 3). Keeps the number's precision if +nil+.
129
+ # * <tt>:round_mode</tt> - Determine how rounding is performed
130
+ # (defaults to :default. See BigDecimal::mode)
114
131
  # * <tt>:significant</tt> - If +true+, precision will be the number
115
132
  # of significant_digits. If +false+, the number of fractional
116
133
  # digits (defaults to +false+).
@@ -126,15 +143,16 @@ module ActiveSupport
126
143
  #
127
144
  # ==== Examples
128
145
  #
129
- # number_to_percentage(100) # => "100.000%"
130
- # number_to_percentage('98') # => "98.000%"
131
- # number_to_percentage(100, precision: 0) # => "100%"
132
- # number_to_percentage(1000, delimiter: '.', separator: ',') # => "1.000,000%"
133
- # number_to_percentage(302.24398923423, precision: 5) # => "302.24399%"
134
- # number_to_percentage(1000, locale: :fr) # => "1000,000%"
135
- # number_to_percentage(1000, precision: nil) # => "1000%"
136
- # number_to_percentage('98a') # => "98a%"
137
- # number_to_percentage(100, format: '%n %') # => "100.000 %"
146
+ # number_to_percentage(100) # => "100.000%"
147
+ # number_to_percentage('98') # => "98.000%"
148
+ # number_to_percentage(100, precision: 0) # => "100%"
149
+ # number_to_percentage(1000, delimiter: '.', separator: ',') # => "1.000,000%"
150
+ # number_to_percentage(302.24398923423, precision: 5) # => "302.24399%"
151
+ # number_to_percentage(1000, locale: :fr) # => "1000,000%"
152
+ # number_to_percentage(1000, precision: nil) # => "1000%"
153
+ # number_to_percentage('98a') # => "98a%"
154
+ # number_to_percentage(100, format: '%n %') # => "100.000 %"
155
+ # number_to_percentage(302.24398923423, precision: 5, round_mode: :down) # => "302.24398%"
138
156
  def number_to_percentage(number, options = {})
139
157
  NumberToPercentageConverter.convert(number, options)
140
158
  end
@@ -185,6 +203,8 @@ module ActiveSupport
185
203
  # (defaults to current locale).
186
204
  # * <tt>:precision</tt> - Sets the precision of the number
187
205
  # (defaults to 3). Keeps the number's precision if +nil+.
206
+ # * <tt>:round_mode</tt> - Determine how rounding is performed
207
+ # (defaults to :default. See BigDecimal::mode)
188
208
  # * <tt>:significant</tt> - If +true+, precision will be the number
189
209
  # of significant_digits. If +false+, the number of fractional
190
210
  # digits (defaults to +false+).
@@ -206,6 +226,7 @@ module ActiveSupport
206
226
  # number_to_rounded(111.2345, precision: 1, significant: true) # => "100"
207
227
  # number_to_rounded(13, precision: 5, significant: true) # => "13.000"
208
228
  # number_to_rounded(13, precision: nil) # => "13"
229
+ # number_to_rounded(389.32314, precision: 0, round_mode: :up) # => "390"
209
230
  # number_to_rounded(111.234, locale: :fr) # => "111,234"
210
231
  #
211
232
  # number_to_rounded(13, precision: 5, significant: true, strip_insignificant_zeros: true)
@@ -219,7 +240,7 @@ module ActiveSupport
219
240
  end
220
241
 
221
242
  # Formats the bytes in +number+ into a more understandable
222
- # representation (e.g., giving it 1500 yields 1.5 KB). This
243
+ # representation (e.g., giving it 1500 yields 1.46 KB). This
223
244
  # method is useful for reporting file sizes to users. You can
224
245
  # customize the format in the +options+ hash.
225
246
  #
@@ -232,6 +253,8 @@ module ActiveSupport
232
253
  # (defaults to current locale).
233
254
  # * <tt>:precision</tt> - Sets the precision of the number
234
255
  # (defaults to 3).
256
+ # * <tt>:round_mode</tt> - Determine how rounding is performed
257
+ # (defaults to :default. See BigDecimal::mode)
235
258
  # * <tt>:significant</tt> - If +true+, precision will be the number
236
259
  # of significant_digits. If +false+, the number of fractional
237
260
  # digits (defaults to +true+)
@@ -255,6 +278,7 @@ module ActiveSupport
255
278
  # number_to_human_size(1234567890123456789) # => "1.07 EB"
256
279
  # number_to_human_size(1234567, precision: 2) # => "1.2 MB"
257
280
  # number_to_human_size(483989, precision: 2) # => "470 KB"
281
+ # number_to_human_size(483989, precision: 2, round_mode: :up) # => "480 KB"
258
282
  # number_to_human_size(1234567, precision: 2, separator: ',') # => "1,2 MB"
259
283
  # number_to_human_size(1234567890123, precision: 5) # => "1.1228 TB"
260
284
  # number_to_human_size(524288000, precision: 5) # => "500 MB"
@@ -263,7 +287,7 @@ module ActiveSupport
263
287
  end
264
288
 
265
289
  # Pretty prints (formats and approximates) a number in a way it
266
- # is more readable by humans (eg.: 1200000000 becomes "1.2
290
+ # is more readable by humans (e.g.: 1200000000 becomes "1.2
267
291
  # Billion"). This is useful for numbers that can get very large
268
292
  # (and too hard to read).
269
293
  #
@@ -271,7 +295,7 @@ module ActiveSupport
271
295
  # size.
272
296
  #
273
297
  # You can also define your own unit-quantifier names if you want
274
- # to use other decimal units (eg.: 1500 becomes "1.5
298
+ # to use other decimal units (e.g.: 1500 becomes "1.5
275
299
  # kilometers", 0.150 becomes "150 milliliters", etc). You may
276
300
  # define a wide range of unit quantifiers, even fractional ones
277
301
  # (centi, deci, mili, etc).
@@ -282,6 +306,8 @@ module ActiveSupport
282
306
  # (defaults to current locale).
283
307
  # * <tt>:precision</tt> - Sets the precision of the number
284
308
  # (defaults to 3).
309
+ # * <tt>:round_mode</tt> - Determine how rounding is performed
310
+ # (defaults to :default. See BigDecimal::mode)
285
311
  # * <tt>:significant</tt> - If +true+, precision will be the number
286
312
  # of significant_digits. If +false+, the number of fractional
287
313
  # digits (defaults to +true+)
@@ -319,6 +345,8 @@ module ActiveSupport
319
345
  # number_to_human(1234567890123456789) # => "1230 Quadrillion"
320
346
  # number_to_human(489939, precision: 2) # => "490 Thousand"
321
347
  # number_to_human(489939, precision: 4) # => "489.9 Thousand"
348
+ # number_to_human(489939, precision: 2
349
+ # , round_mode: :down) # => "480 Thousand"
322
350
  # number_to_human(1234567, precision: 4,
323
351
  # significant: false) # => "1.2346 Million"
324
352
  # number_to_human(1234567, precision: 1,
@@ -1,9 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/hash/deep_merge"
4
+ require "active_support/core_ext/symbol/starts_ends_with"
2
5
 
3
6
  module ActiveSupport
4
7
  class OptionMerger #:nodoc:
5
8
  instance_methods.each do |method|
6
- undef_method(method) if method !~ /^(__|instance_eval|class|object_id)/
9
+ undef_method(method) unless method.start_with?("__", "instance_eval", "class", "object_id")
7
10
  end
8
11
 
9
12
  def initialize(context, options)
@@ -12,14 +15,32 @@ module ActiveSupport
12
15
 
13
16
  private
14
17
  def method_missing(method, *arguments, &block)
18
+ options = nil
15
19
  if arguments.first.is_a?(Proc)
16
20
  proc = arguments.pop
17
21
  arguments << lambda { |*args| @options.deep_merge(proc.call(*args)) }
22
+ elsif arguments.last.respond_to?(:to_hash)
23
+ options = @options.deep_merge(arguments.pop)
18
24
  else
19
- arguments << (arguments.last.respond_to?(:to_hash) ? @options.deep_merge(arguments.pop) : @options.dup)
25
+ options = @options
20
26
  end
21
27
 
22
- @context.__send__(method, *arguments, &block)
28
+ invoke_method(method, arguments, options, &block)
29
+ end
30
+
31
+ if RUBY_VERSION >= "2.7"
32
+ def invoke_method(method, arguments, options, &block)
33
+ if options
34
+ @context.__send__(method, *arguments, **options, &block)
35
+ else
36
+ @context.__send__(method, *arguments, &block)
37
+ end
38
+ end
39
+ else
40
+ def invoke_method(method, arguments, options, &block)
41
+ arguments << options.dup if options
42
+ @context.__send__(method, *arguments, &block)
43
+ end
23
44
  end
24
45
  end
25
46
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "yaml"
2
4
 
3
5
  YAML.add_builtin_type("omap") do |type, val|
@@ -14,7 +16,7 @@ module ActiveSupport
14
16
  # oh.keys # => [:a, :b], this order is guaranteed
15
17
  #
16
18
  # Also, maps the +omap+ feature for YAML files
17
- # (See http://yaml.org/type/omap.html) to support ordered items
19
+ # (See https://yaml.org/type/omap.html) to support ordered items
18
20
  # when loading from yaml.
19
21
  #
20
22
  # <tt>ActiveSupport::OrderedHash</tt> is namespaced to prevent conflicts
@@ -1,7 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/object/blank"
2
4
 
3
5
  module ActiveSupport
4
- # Usually key value pairs are handled something like this:
6
+ # +OrderedOptions+ inherits from +Hash+ and provides dynamic accessor methods.
7
+ #
8
+ # With a +Hash+, key-value pairs are typically managed like this:
5
9
  #
6
10
  # h = {}
7
11
  # h[:boy] = 'John'
@@ -10,7 +14,7 @@ module ActiveSupport
10
14
  # h[:girl] # => 'Mary'
11
15
  # h[:dog] # => nil
12
16
  #
13
- # Using +OrderedOptions+, the above code could be reduced to:
17
+ # Using +OrderedOptions+, the above code can be written as:
14
18
  #
15
19
  # h = ActiveSupport::OrderedOptions.new
16
20
  # h.boy = 'John'
@@ -22,7 +26,7 @@ module ActiveSupport
22
26
  # To raise an exception when the value is blank, append a
23
27
  # bang to the key name, like:
24
28
  #
25
- # h.dog! # => raises KeyError: key not found: :dog
29
+ # h.dog! # => raises KeyError: :dog is blank
26
30
  #
27
31
  class OrderedOptions < Hash
28
32
  alias_method :_get, :[] # preserve the original #[] method
@@ -37,14 +41,14 @@ module ActiveSupport
37
41
  end
38
42
 
39
43
  def method_missing(name, *args)
40
- name_string = name.to_s
44
+ name_string = +name.to_s
41
45
  if name_string.chomp!("=")
42
46
  self[name_string] = args.first
43
47
  else
44
48
  bangs = name_string.chomp!("!")
45
49
 
46
50
  if bangs
47
- fetch(name_string.to_sym).presence || raise(KeyError.new("#{name_string} is blank."))
51
+ self[name_string].presence || raise(KeyError.new(":#{name_string} is blank"))
48
52
  else
49
53
  self[name_string]
50
54
  end
@@ -54,6 +58,14 @@ module ActiveSupport
54
58
  def respond_to_missing?(name, include_private)
55
59
  true
56
60
  end
61
+
62
+ def extractable_options?
63
+ true
64
+ end
65
+
66
+ def inspect
67
+ "#<#{self.class.name} #{super}>"
68
+ end
57
69
  end
58
70
 
59
71
  # +InheritableOptions+ provides a constructor to build an +OrderedOptions+
@@ -0,0 +1,133 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/object/duplicable"
4
+
5
+ module ActiveSupport
6
+ # +ParameterFilter+ allows you to specify keys for sensitive data from
7
+ # hash-like object and replace corresponding value. Filtering only certain
8
+ # sub-keys from a hash is possible by using the dot notation:
9
+ # 'credit_card.number'. If a proc is given, each key and value of a hash and
10
+ # all sub-hashes are passed to it, where the value or the key can be replaced
11
+ # using String#replace or similar methods.
12
+ #
13
+ # ActiveSupport::ParameterFilter.new([:password])
14
+ # => replaces the value to all keys matching /password/i with "[FILTERED]"
15
+ #
16
+ # ActiveSupport::ParameterFilter.new([:foo, "bar"])
17
+ # => replaces the value to all keys matching /foo|bar/i with "[FILTERED]"
18
+ #
19
+ # ActiveSupport::ParameterFilter.new(["credit_card.code"])
20
+ # => replaces { credit_card: {code: "xxxx"} } with "[FILTERED]", does not
21
+ # change { file: { code: "xxxx"} }
22
+ #
23
+ # ActiveSupport::ParameterFilter.new([-> (k, v) do
24
+ # v.reverse! if /secret/i.match?(k)
25
+ # end])
26
+ # => reverses the value to all keys matching /secret/i
27
+ class ParameterFilter
28
+ FILTERED = "[FILTERED]" # :nodoc:
29
+
30
+ # Create instance with given filters. Supported type of filters are +String+, +Regexp+, and +Proc+.
31
+ # Other types of filters are treated as +String+ using +to_s+.
32
+ # For +Proc+ filters, key, value, and optional original hash is passed to block arguments.
33
+ #
34
+ # ==== Options
35
+ #
36
+ # * <tt>:mask</tt> - A replaced object when filtered. Defaults to <tt>"[FILTERED]"</tt>.
37
+ def initialize(filters = [], mask: FILTERED)
38
+ @filters = filters
39
+ @mask = mask
40
+ end
41
+
42
+ # Mask value of +params+ if key matches one of filters.
43
+ def filter(params)
44
+ compiled_filter.call(params)
45
+ end
46
+
47
+ # Returns filtered value for given key. For +Proc+ filters, third block argument is not populated.
48
+ def filter_param(key, value)
49
+ @filters.empty? ? value : compiled_filter.value_for_key(key, value)
50
+ end
51
+
52
+ private
53
+ def compiled_filter
54
+ @compiled_filter ||= CompiledFilter.compile(@filters, mask: @mask)
55
+ end
56
+
57
+ class CompiledFilter # :nodoc:
58
+ def self.compile(filters, mask:)
59
+ return lambda { |params| params.dup } if filters.empty?
60
+
61
+ strings, regexps, blocks, deep_regexps, deep_strings = [], [], [], nil, nil
62
+
63
+ filters.each do |item|
64
+ case item
65
+ when Proc
66
+ blocks << item
67
+ when Regexp
68
+ if item.to_s.include?("\\.")
69
+ (deep_regexps ||= []) << item
70
+ else
71
+ regexps << item
72
+ end
73
+ else
74
+ s = Regexp.escape(item.to_s)
75
+ if s.include?("\\.")
76
+ (deep_strings ||= []) << s
77
+ else
78
+ strings << s
79
+ end
80
+ end
81
+ end
82
+
83
+ regexps << Regexp.new(strings.join("|"), true) unless strings.empty?
84
+ (deep_regexps ||= []) << Regexp.new(deep_strings.join("|"), true) if deep_strings&.any?
85
+
86
+ new regexps, deep_regexps, blocks, mask: mask
87
+ end
88
+
89
+ attr_reader :regexps, :deep_regexps, :blocks
90
+
91
+ def initialize(regexps, deep_regexps, blocks, mask:)
92
+ @regexps = regexps
93
+ @deep_regexps = deep_regexps&.any? ? deep_regexps : nil
94
+ @blocks = blocks
95
+ @mask = mask
96
+ end
97
+
98
+ def call(params, parents = [], original_params = params)
99
+ filtered_params = params.class.new
100
+
101
+ params.each do |key, value|
102
+ filtered_params[key] = value_for_key(key, value, parents, original_params)
103
+ end
104
+
105
+ filtered_params
106
+ end
107
+
108
+ def value_for_key(key, value, parents = [], original_params = nil)
109
+ parents.push(key) if deep_regexps
110
+ if regexps.any? { |r| r.match?(key.to_s) }
111
+ value = @mask
112
+ elsif deep_regexps && (joined = parents.join(".")) && deep_regexps.any? { |r| r.match?(joined) }
113
+ value = @mask
114
+ elsif value.is_a?(Hash)
115
+ value = call(value, parents, original_params)
116
+ elsif value.is_a?(Array)
117
+ # If we don't pop the current parent it will be duplicated as we
118
+ # process each array value.
119
+ parents.pop if deep_regexps
120
+ value = value.map { |v| value_for_key(key, v, parents, original_params) }
121
+ # Restore the parent stack after processing the array.
122
+ parents.push(key) if deep_regexps
123
+ elsif blocks.any?
124
+ key = key.dup if key.duplicable?
125
+ value = value.dup if value.duplicable?
126
+ blocks.each { |b| b.arity == 2 ? b.call(key, value) : b.call(key, value, original_params) }
127
+ end
128
+ parents.pop if deep_regexps
129
+ value
130
+ end
131
+ end
132
+ end
133
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/module/delegation"
2
4
 
3
5
  module ActiveSupport
@@ -38,7 +40,7 @@ module ActiveSupport
38
40
  # If the class has an initializer, it must accept no arguments.
39
41
  module PerThreadRegistry
40
42
  def self.extended(object)
41
- object.instance_variable_set "@per_thread_registry_key", object.name.freeze
43
+ object.instance_variable_set :@per_thread_registry_key, object.name.freeze
42
44
  end
43
45
 
44
46
  def instance
@@ -54,5 +56,6 @@ module ActiveSupport
54
56
 
55
57
  send(name, *args, &block)
56
58
  end
59
+ ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
57
60
  end
58
61
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  # A class with no predefined methods that behaves similarly to Builder's
3
5
  # BlankSlate. Used for proxy classes.
@@ -1,4 +1,6 @@
1
- # This is private interface.
1
+ # frozen_string_literal: true
2
+
3
+ # This is a private interface.
2
4
  #
3
5
  # Rails components cherry pick from Active Support as needed, but there are a
4
6
  # few features that are used for sure in some way or another and it is not worth
@@ -11,9 +13,6 @@
11
13
  # Defines Object#blank? and Object#present?.
12
14
  require "active_support/core_ext/object/blank"
13
15
 
14
- # Rails own autoload, eager_load, etc.
15
- require "active_support/dependencies/autoload"
16
-
17
16
  # Support for ClassMethods and the included macro.
18
17
  require "active_support/concern"
19
18
 
@@ -25,9 +24,3 @@ require "active_support/core_ext/module/delegation"
25
24
 
26
25
  # Defines ActiveSupport::Deprecation.
27
26
  require "active_support/deprecation"
28
-
29
- # Defines Regexp#match?.
30
- #
31
- # This should be removed when Rails needs Ruby 2.4 or later, and the require
32
- # added where other Regexp extensions are being used (easy to grep).
33
- require "active_support/core_ext/regexp"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support"
2
4
  require "active_support/i18n_railtie"
3
5
 
@@ -7,10 +9,38 @@ module ActiveSupport
7
9
 
8
10
  config.eager_load_namespaces << ActiveSupport
9
11
 
12
+ initializer "active_support.set_authenticated_message_encryption" do |app|
13
+ config.after_initialize do
14
+ unless app.config.active_support.use_authenticated_message_encryption.nil?
15
+ ActiveSupport::MessageEncryptor.use_authenticated_message_encryption =
16
+ app.config.active_support.use_authenticated_message_encryption
17
+ end
18
+ end
19
+ end
20
+
21
+ initializer "active_support.reset_all_current_attributes_instances" do |app|
22
+ app.reloader.before_class_unload { ActiveSupport::CurrentAttributes.clear_all }
23
+ app.executor.to_run { ActiveSupport::CurrentAttributes.reset_all }
24
+ app.executor.to_complete { ActiveSupport::CurrentAttributes.reset_all }
25
+
26
+ ActiveSupport.on_load(:active_support_test_case) do
27
+ require "active_support/current_attributes/test_helper"
28
+ include ActiveSupport::CurrentAttributes::TestHelper
29
+ end
30
+ end
31
+
10
32
  initializer "active_support.deprecation_behavior" do |app|
11
33
  if deprecation = app.config.active_support.deprecation
12
34
  ActiveSupport::Deprecation.behavior = deprecation
13
35
  end
36
+
37
+ if disallowed_deprecation = app.config.active_support.disallowed_deprecation
38
+ ActiveSupport::Deprecation.disallowed_behavior = disallowed_deprecation
39
+ end
40
+
41
+ if disallowed_warnings = app.config.active_support.disallowed_deprecation_warnings
42
+ ActiveSupport::Deprecation.disallowed_warnings = disallowed_warnings
43
+ end
14
44
  end
15
45
 
16
46
  # Sets the default value for Time.zone
@@ -22,14 +52,7 @@ module ActiveSupport
22
52
  raise e.exception "tzinfo-data is not present. Please add gem 'tzinfo-data' to your Gemfile and run bundle install"
23
53
  end
24
54
  require "active_support/core_ext/time/zones"
25
- zone_default = Time.find_zone!(app.config.time_zone)
26
-
27
- unless zone_default
28
- raise "Value assigned to config.time_zone not recognized. " \
29
- 'Run "rake time:zones:all" for a time zone names list.'
30
- end
31
-
32
- Time.zone_default = zone_default
55
+ Time.zone_default = Time.find_zone!(app.config.time_zone)
33
56
  end
34
57
 
35
58
  # Sets the default week start
@@ -41,10 +64,38 @@ module ActiveSupport
41
64
  Date.beginning_of_week_default = beginning_of_week_default
42
65
  end
43
66
 
67
+ initializer "active_support.require_master_key" do |app|
68
+ if app.config.respond_to?(:require_master_key) && app.config.require_master_key
69
+ begin
70
+ app.credentials.key
71
+ rescue ActiveSupport::EncryptedFile::MissingKeyError => error
72
+ $stderr.puts error.message
73
+ exit 1
74
+ end
75
+ end
76
+ end
77
+
44
78
  initializer "active_support.set_configs" do |app|
45
79
  app.config.active_support.each do |k, v|
46
80
  k = "#{k}="
47
- ActiveSupport.send(k, v) if ActiveSupport.respond_to? k
81
+ ActiveSupport.public_send(k, v) if ActiveSupport.respond_to? k
82
+ end
83
+ end
84
+
85
+ initializer "active_support.set_hash_digest_class" do |app|
86
+ config.after_initialize do
87
+ if app.config.active_support.use_sha1_digests
88
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
89
+ config.active_support.use_sha1_digests is deprecated and will
90
+ be removed from Rails 7.0. Use
91
+ config.active_support.hash_digest_class = ::Digest::SHA1 instead.
92
+ MSG
93
+ ActiveSupport::Digest.hash_digest_class = ::Digest::SHA1
94
+ end
95
+
96
+ if klass = app.config.active_support.hash_digest_class
97
+ ActiveSupport::Digest.hash_digest_class = klass
98
+ end
48
99
  end
49
100
  end
50
101
  end
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/execution_wrapper"
4
+ require "active_support/executor"
2
5
 
3
6
  module ActiveSupport
4
7
  #--
@@ -26,14 +29,17 @@ module ActiveSupport
26
29
 
27
30
  define_callbacks :class_unload
28
31
 
32
+ # Registers a callback that will run once at application startup and every time the code is reloaded.
29
33
  def self.to_prepare(*args, &block)
30
34
  set_callback(:prepare, *args, &block)
31
35
  end
32
36
 
37
+ # Registers a callback that will run immediately before the classes are unloaded.
33
38
  def self.before_class_unload(*args, &block)
34
39
  set_callback(:class_unload, *args, &block)
35
40
  end
36
41
 
42
+ # Registers a callback that will run immediately after the classes are unloaded.
37
43
  def self.after_class_unload(*args, &block)
38
44
  set_callback(:class_unload, :after, *args, &block)
39
45
  end
@@ -44,17 +50,15 @@ module ActiveSupport
44
50
  def self.reload!
45
51
  executor.wrap do
46
52
  new.tap do |instance|
47
- begin
48
- instance.run!
49
- ensure
50
- instance.complete!
51
- end
53
+ instance.run!
54
+ ensure
55
+ instance.complete!
52
56
  end
53
57
  end
54
58
  prepare!
55
59
  end
56
60
 
57
- def self.run! # :nodoc:
61
+ def self.run!(reset: false) # :nodoc:
58
62
  if check!
59
63
  super
60
64
  else
@@ -69,11 +73,8 @@ module ActiveSupport
69
73
  end
70
74
  end
71
75
 
72
- class_attribute :executor
73
- class_attribute :check
74
-
75
- self.executor = Executor
76
- self.check = lambda { false }
76
+ class_attribute :executor, default: Executor
77
+ class_attribute :check, default: lambda { false }
77
78
 
78
79
  def self.check! # :nodoc:
79
80
  @should_reload ||= check.call
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/concern"
2
4
  require "active_support/core_ext/class/attribute"
3
5
  require "active_support/core_ext/string/inflections"
@@ -8,17 +10,16 @@ module ActiveSupport
8
10
  extend Concern
9
11
 
10
12
  included do
11
- class_attribute :rescue_handlers
12
- self.rescue_handlers = []
13
+ class_attribute :rescue_handlers, default: []
13
14
  end
14
15
 
15
16
  module ClassMethods
16
- # Rescue exceptions raised in controller actions.
17
+ # Registers exception classes with a handler to be called by <tt>rescue_with_handler</tt>.
17
18
  #
18
19
  # <tt>rescue_from</tt> receives a series of exception classes or class
19
- # names, and a trailing <tt>:with</tt> option with the name of a method
20
- # or a Proc object to be called to handle them. Alternatively a block can
21
- # be given.
20
+ # names, and an exception handler specified by a trailing <tt>:with</tt>
21
+ # option containing the name of a method or a Proc object. Alternatively, a block
22
+ # can be given as the handler.
22
23
  #
23
24
  # Handlers that take one argument will be called with the exception, so
24
25
  # that the exception can be inspected when dealing with it.