activesupport 5.1.1 → 6.1.1

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 +5 -5
  2. data/CHANGELOG.md +360 -442
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +5 -4
  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 +65 -53
  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 +68 -22
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
  18. data/lib/active_support/cache.rb +305 -127
  19. data/lib/active_support/callbacks.rb +106 -98
  20. data/lib/active_support/concern.rb +79 -6
  21. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +35 -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 +46 -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 +3 -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 +6 -101
  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 +7 -2
  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 +76 -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 +73 -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 +208 -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 +117 -0
  146. data/lib/active_support/dependencies.rb +135 -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 +30 -15
  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 +20 -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 +179 -41
  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 +3 -0
  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 +62 -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 +134 -37
  171. data/lib/active_support/i18n.rb +4 -1
  172. data/lib/active_support/i18n_railtie.rb +20 -11
  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 +33 -10
  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 +46 -13
  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 +101 -33
  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 +8 -7
  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 +16 -53
  209. data/lib/active_support/number_helper/rounding_helper.rb +50 -0
  210. data/lib/active_support/number_helper.rb +41 -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 +3 -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 +11 -10
  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 -4
  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 +8 -4
  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 +55 -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 +81 -35
  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,9 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  module NumberHelper
3
5
  extend ActiveSupport::Autoload
4
6
 
5
7
  eager_autoload do
6
8
  autoload :NumberConverter
9
+ autoload :RoundingHelper
7
10
  autoload :NumberToRoundedConverter
8
11
  autoload :NumberToDelimitedConverter
9
12
  autoload :NumberToHumanConverter
@@ -68,6 +71,8 @@ module ActiveSupport
68
71
  # (defaults to current locale).
69
72
  # * <tt>:precision</tt> - Sets the level of precision (defaults
70
73
  # to 2).
74
+ # * <tt>:round_mode</tt> - Determine how rounding is performed
75
+ # (defaults to :default. See BigDecimal::mode)
71
76
  # * <tt>:unit</tt> - Sets the denomination of the currency
72
77
  # (defaults to "$").
73
78
  # * <tt>:separator</tt> - Sets the separator between the units
@@ -82,6 +87,9 @@ module ActiveSupport
82
87
  # number given by <tt>:format</tt>). Accepts the same fields
83
88
  # than <tt>:format</tt>, except <tt>%n</tt> is here the
84
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+).
85
93
  #
86
94
  # ==== Examples
87
95
  #
@@ -91,12 +99,20 @@ module ActiveSupport
91
99
  # number_to_currency(1234567890.506, locale: :fr) # => "1 234 567 890,51 €"
92
100
  # number_to_currency('123a456') # => "$123a456"
93
101
  #
102
+ # number_to_currency("123a456", raise: true) # => InvalidNumberError
103
+ #
104
+ # number_to_currency(-0.456789, precision: 0)
105
+ # # => "$0"
94
106
  # number_to_currency(-1234567890.50, negative_format: '(%u%n)')
95
107
  # # => "($1,234,567,890.50)"
96
108
  # number_to_currency(1234567890.50, unit: '&pound;', separator: ',', delimiter: '')
97
109
  # # => "&pound;1234567890,50"
98
110
  # number_to_currency(1234567890.50, unit: '&pound;', separator: ',', delimiter: '', format: '%n %u')
99
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"
100
116
  def number_to_currency(number, options = {})
101
117
  NumberToCurrencyConverter.convert(number, options)
102
118
  end
@@ -110,6 +126,8 @@ module ActiveSupport
110
126
  # (defaults to current locale).
111
127
  # * <tt>:precision</tt> - Sets the precision of the number
112
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)
113
131
  # * <tt>:significant</tt> - If +true+, precision will be the number
114
132
  # of significant_digits. If +false+, the number of fractional
115
133
  # digits (defaults to +false+).
@@ -125,15 +143,16 @@ module ActiveSupport
125
143
  #
126
144
  # ==== Examples
127
145
  #
128
- # number_to_percentage(100) # => "100.000%"
129
- # number_to_percentage('98') # => "98.000%"
130
- # number_to_percentage(100, precision: 0) # => "100%"
131
- # number_to_percentage(1000, delimiter: '.', separator: ',') # => "1.000,000%"
132
- # number_to_percentage(302.24398923423, precision: 5) # => "302.24399%"
133
- # number_to_percentage(1000, locale: :fr) # => "1000,000%"
134
- # number_to_percentage(1000, precision: nil) # => "1000%"
135
- # number_to_percentage('98a') # => "98a%"
136
- # 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%"
137
156
  def number_to_percentage(number, options = {})
138
157
  NumberToPercentageConverter.convert(number, options)
139
158
  end
@@ -184,6 +203,8 @@ module ActiveSupport
184
203
  # (defaults to current locale).
185
204
  # * <tt>:precision</tt> - Sets the precision of the number
186
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)
187
208
  # * <tt>:significant</tt> - If +true+, precision will be the number
188
209
  # of significant_digits. If +false+, the number of fractional
189
210
  # digits (defaults to +false+).
@@ -205,6 +226,7 @@ module ActiveSupport
205
226
  # number_to_rounded(111.2345, precision: 1, significant: true) # => "100"
206
227
  # number_to_rounded(13, precision: 5, significant: true) # => "13.000"
207
228
  # number_to_rounded(13, precision: nil) # => "13"
229
+ # number_to_rounded(389.32314, precision: 0, round_mode: :up) # => "390"
208
230
  # number_to_rounded(111.234, locale: :fr) # => "111,234"
209
231
  #
210
232
  # number_to_rounded(13, precision: 5, significant: true, strip_insignificant_zeros: true)
@@ -218,7 +240,7 @@ module ActiveSupport
218
240
  end
219
241
 
220
242
  # Formats the bytes in +number+ into a more understandable
221
- # representation (e.g., giving it 1500 yields 1.5 KB). This
243
+ # representation (e.g., giving it 1500 yields 1.46 KB). This
222
244
  # method is useful for reporting file sizes to users. You can
223
245
  # customize the format in the +options+ hash.
224
246
  #
@@ -231,6 +253,8 @@ module ActiveSupport
231
253
  # (defaults to current locale).
232
254
  # * <tt>:precision</tt> - Sets the precision of the number
233
255
  # (defaults to 3).
256
+ # * <tt>:round_mode</tt> - Determine how rounding is performed
257
+ # (defaults to :default. See BigDecimal::mode)
234
258
  # * <tt>:significant</tt> - If +true+, precision will be the number
235
259
  # of significant_digits. If +false+, the number of fractional
236
260
  # digits (defaults to +true+)
@@ -254,6 +278,7 @@ module ActiveSupport
254
278
  # number_to_human_size(1234567890123456789) # => "1.07 EB"
255
279
  # number_to_human_size(1234567, precision: 2) # => "1.2 MB"
256
280
  # number_to_human_size(483989, precision: 2) # => "470 KB"
281
+ # number_to_human_size(483989, precision: 2, round_mode: :up) # => "480 KB"
257
282
  # number_to_human_size(1234567, precision: 2, separator: ',') # => "1,2 MB"
258
283
  # number_to_human_size(1234567890123, precision: 5) # => "1.1228 TB"
259
284
  # number_to_human_size(524288000, precision: 5) # => "500 MB"
@@ -262,7 +287,7 @@ module ActiveSupport
262
287
  end
263
288
 
264
289
  # Pretty prints (formats and approximates) a number in a way it
265
- # is more readable by humans (eg.: 1200000000 becomes "1.2
290
+ # is more readable by humans (e.g.: 1200000000 becomes "1.2
266
291
  # Billion"). This is useful for numbers that can get very large
267
292
  # (and too hard to read).
268
293
  #
@@ -270,7 +295,7 @@ module ActiveSupport
270
295
  # size.
271
296
  #
272
297
  # You can also define your own unit-quantifier names if you want
273
- # to use other decimal units (eg.: 1500 becomes "1.5
298
+ # to use other decimal units (e.g.: 1500 becomes "1.5
274
299
  # kilometers", 0.150 becomes "150 milliliters", etc). You may
275
300
  # define a wide range of unit quantifiers, even fractional ones
276
301
  # (centi, deci, mili, etc).
@@ -281,6 +306,8 @@ module ActiveSupport
281
306
  # (defaults to current locale).
282
307
  # * <tt>:precision</tt> - Sets the precision of the number
283
308
  # (defaults to 3).
309
+ # * <tt>:round_mode</tt> - Determine how rounding is performed
310
+ # (defaults to :default. See BigDecimal::mode)
284
311
  # * <tt>:significant</tt> - If +true+, precision will be the number
285
312
  # of significant_digits. If +false+, the number of fractional
286
313
  # digits (defaults to +true+)
@@ -318,6 +345,8 @@ module ActiveSupport
318
345
  # number_to_human(1234567890123456789) # => "1230 Quadrillion"
319
346
  # number_to_human(489939, precision: 2) # => "490 Thousand"
320
347
  # number_to_human(489939, precision: 4) # => "489.9 Thousand"
348
+ # number_to_human(489939, precision: 2
349
+ # , round_mode: :down) # => "480 Thousand"
321
350
  # number_to_human(1234567, precision: 4,
322
351
  # significant: false) # => "1.2346 Million"
323
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 +"[FILTERED]"+
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
@@ -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 6.2. 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,11 +50,9 @@ 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!
@@ -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.