activesupport 5.1.7 → 7.0.4.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 (279) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +259 -585
  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 +4 -2
  8. data/lib/active_support/backtrace_cleaner.rb +33 -5
  9. data/lib/active_support/benchmarkable.rb +5 -3
  10. data/lib/active_support/builder.rb +2 -0
  11. data/lib/active_support/cache/file_store.rb +50 -43
  12. data/lib/active_support/cache/mem_cache_store.rb +194 -67
  13. data/lib/active_support/cache/memory_store.rb +70 -34
  14. data/lib/active_support/cache/null_store.rb +18 -3
  15. data/lib/active_support/cache/redis_cache_store.rb +474 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +73 -50
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
  18. data/lib/active_support/cache.rb +556 -220
  19. data/lib/active_support/callbacks.rb +264 -159
  20. data/lib/active_support/code_generator.rb +65 -0
  21. data/lib/active_support/concern.rb +81 -8
  22. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +16 -0
  23. data/lib/active_support/concurrency/share_lock.rb +4 -3
  24. data/lib/active_support/configurable.rb +17 -16
  25. data/lib/active_support/configuration_file.rb +51 -0
  26. data/lib/active_support/core_ext/array/access.rb +18 -8
  27. data/lib/active_support/core_ext/array/conversions.rb +20 -17
  28. data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
  29. data/lib/active_support/core_ext/array/extract.rb +21 -0
  30. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  31. data/lib/active_support/core_ext/array/grouping.rb +8 -6
  32. data/lib/active_support/core_ext/array/inquiry.rb +4 -2
  33. data/lib/active_support/core_ext/array/wrap.rb +2 -0
  34. data/lib/active_support/core_ext/array.rb +4 -1
  35. data/lib/active_support/core_ext/benchmark.rb +4 -2
  36. data/lib/active_support/core_ext/big_decimal/conversions.rb +3 -1
  37. data/lib/active_support/core_ext/big_decimal.rb +2 -0
  38. data/lib/active_support/core_ext/class/attribute.rb +50 -47
  39. data/lib/active_support/core_ext/class/attribute_accessors.rb +2 -0
  40. data/lib/active_support/core_ext/class/subclasses.rb +10 -24
  41. data/lib/active_support/core_ext/class.rb +2 -0
  42. data/lib/active_support/core_ext/date/acts_like.rb +2 -0
  43. data/lib/active_support/core_ext/date/blank.rb +3 -1
  44. data/lib/active_support/core_ext/date/calculations.rb +17 -14
  45. data/lib/active_support/core_ext/date/conversions.rb +24 -22
  46. data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
  47. data/lib/active_support/core_ext/date/zones.rb +2 -0
  48. data/lib/active_support/core_ext/date.rb +3 -0
  49. data/lib/active_support/core_ext/date_and_time/calculations.rb +65 -41
  50. data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -1
  51. data/lib/active_support/core_ext/date_and_time/zones.rb +2 -1
  52. data/lib/active_support/core_ext/date_time/acts_like.rb +2 -0
  53. data/lib/active_support/core_ext/date_time/blank.rb +3 -1
  54. data/lib/active_support/core_ext/date_time/calculations.rb +3 -1
  55. data/lib/active_support/core_ext/date_time/compatibility.rb +7 -5
  56. data/lib/active_support/core_ext/date_time/conversions.rb +15 -14
  57. data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
  58. data/lib/active_support/core_ext/date_time.rb +3 -0
  59. data/lib/active_support/core_ext/digest/uuid.rb +42 -14
  60. data/lib/active_support/core_ext/digest.rb +3 -0
  61. data/lib/active_support/core_ext/enumerable.rb +244 -72
  62. data/lib/active_support/core_ext/file/atomic.rb +6 -2
  63. data/lib/active_support/core_ext/file.rb +2 -0
  64. data/lib/active_support/core_ext/hash/conversions.rb +7 -6
  65. data/lib/active_support/core_ext/hash/deep_merge.rb +8 -12
  66. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  67. data/lib/active_support/core_ext/hash/except.rb +4 -2
  68. data/lib/active_support/core_ext/hash/indifferent_access.rb +5 -3
  69. data/lib/active_support/core_ext/hash/keys.rb +4 -31
  70. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  71. data/lib/active_support/core_ext/hash/slice.rb +8 -29
  72. data/lib/active_support/core_ext/hash.rb +3 -2
  73. data/lib/active_support/core_ext/integer/inflections.rb +2 -0
  74. data/lib/active_support/core_ext/integer/multiple.rb +3 -1
  75. data/lib/active_support/core_ext/integer/time.rb +7 -14
  76. data/lib/active_support/core_ext/integer.rb +2 -0
  77. data/lib/active_support/core_ext/kernel/concern.rb +2 -0
  78. data/lib/active_support/core_ext/kernel/reporting.rb +6 -4
  79. data/lib/active_support/core_ext/kernel/singleton_class.rb +3 -1
  80. data/lib/active_support/core_ext/kernel.rb +2 -1
  81. data/lib/active_support/core_ext/load_error.rb +3 -8
  82. data/lib/active_support/core_ext/module/aliasing.rb +2 -0
  83. data/lib/active_support/core_ext/module/anonymous.rb +2 -0
  84. data/lib/active_support/core_ext/module/attr_internal.rb +4 -2
  85. data/lib/active_support/core_ext/module/attribute_accessors.rb +46 -56
  86. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +36 -27
  87. data/lib/active_support/core_ext/module/concerning.rb +15 -10
  88. data/lib/active_support/core_ext/module/delegation.rb +97 -58
  89. data/lib/active_support/core_ext/module/deprecation.rb +2 -0
  90. data/lib/active_support/core_ext/module/introspection.rb +18 -15
  91. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  92. data/lib/active_support/core_ext/module/remove_method.rb +5 -23
  93. data/lib/active_support/core_ext/module.rb +3 -1
  94. data/lib/active_support/core_ext/name_error.rb +30 -2
  95. data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
  96. data/lib/active_support/core_ext/numeric/conversions.rb +134 -129
  97. data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
  98. data/lib/active_support/core_ext/numeric/time.rb +7 -15
  99. data/lib/active_support/core_ext/numeric.rb +3 -1
  100. data/lib/active_support/core_ext/object/acts_like.rb +41 -6
  101. data/lib/active_support/core_ext/object/blank.rb +15 -5
  102. data/lib/active_support/core_ext/object/conversions.rb +2 -0
  103. data/lib/active_support/core_ext/object/deep_dup.rb +3 -1
  104. data/lib/active_support/core_ext/object/duplicable.rb +16 -110
  105. data/lib/active_support/core_ext/object/inclusion.rb +2 -0
  106. data/lib/active_support/core_ext/object/instance_variables.rb +2 -0
  107. data/lib/active_support/core_ext/object/json.rb +51 -26
  108. data/lib/active_support/core_ext/object/to_param.rb +2 -0
  109. data/lib/active_support/core_ext/object/to_query.rb +4 -2
  110. data/lib/active_support/core_ext/object/try.rb +26 -14
  111. data/lib/active_support/core_ext/object/with_options.rb +24 -3
  112. data/lib/active_support/core_ext/object.rb +2 -0
  113. data/lib/active_support/core_ext/pathname/existence.rb +21 -0
  114. data/lib/active_support/core_ext/pathname.rb +3 -0
  115. data/lib/active_support/core_ext/range/compare_range.rb +57 -0
  116. data/lib/active_support/core_ext/range/conversions.rb +35 -25
  117. data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
  118. data/lib/active_support/core_ext/range/each.rb +6 -3
  119. data/lib/active_support/core_ext/range/include_time_with_zone.rb +7 -0
  120. data/lib/active_support/core_ext/range/overlaps.rb +3 -1
  121. data/lib/active_support/core_ext/range.rb +4 -1
  122. data/lib/active_support/core_ext/regexp.rb +10 -5
  123. data/lib/active_support/core_ext/securerandom.rb +25 -3
  124. data/lib/active_support/core_ext/string/access.rb +7 -16
  125. data/lib/active_support/core_ext/string/behavior.rb +2 -0
  126. data/lib/active_support/core_ext/string/conversions.rb +5 -2
  127. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  128. data/lib/active_support/core_ext/string/filters.rb +44 -1
  129. data/lib/active_support/core_ext/string/indent.rb +2 -0
  130. data/lib/active_support/core_ext/string/inflections.rb +69 -16
  131. data/lib/active_support/core_ext/string/inquiry.rb +4 -1
  132. data/lib/active_support/core_ext/string/multibyte.rb +9 -4
  133. data/lib/active_support/core_ext/string/output_safety.rb +135 -27
  134. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
  135. data/lib/active_support/core_ext/string/strip.rb +5 -1
  136. data/lib/active_support/core_ext/string/zones.rb +2 -0
  137. data/lib/active_support/core_ext/string.rb +2 -0
  138. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
  139. data/lib/active_support/core_ext/symbol.rb +3 -0
  140. data/lib/active_support/core_ext/time/acts_like.rb +2 -0
  141. data/lib/active_support/core_ext/time/calculations.rb +81 -24
  142. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  143. data/lib/active_support/core_ext/time/conversions.rb +17 -12
  144. data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
  145. data/lib/active_support/core_ext/time/zones.rb +12 -25
  146. data/lib/active_support/core_ext/time.rb +3 -0
  147. data/lib/active_support/core_ext/uri.rb +4 -23
  148. data/lib/active_support/core_ext.rb +4 -1
  149. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  150. data/lib/active_support/current_attributes.rb +226 -0
  151. data/lib/active_support/dependencies/autoload.rb +2 -0
  152. data/lib/active_support/dependencies/interlock.rb +12 -18
  153. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  154. data/lib/active_support/dependencies.rb +59 -715
  155. data/lib/active_support/deprecation/behaviors.rb +48 -13
  156. data/lib/active_support/deprecation/constant_accessor.rb +4 -2
  157. data/lib/active_support/deprecation/disallowed.rb +56 -0
  158. data/lib/active_support/deprecation/instance_delegator.rb +2 -1
  159. data/lib/active_support/deprecation/method_wrappers.rb +29 -21
  160. data/lib/active_support/deprecation/proxy_wrappers.rb +34 -8
  161. data/lib/active_support/deprecation/reporting.rb +54 -9
  162. data/lib/active_support/deprecation.rb +10 -3
  163. data/lib/active_support/descendants_tracker.rb +192 -34
  164. data/lib/active_support/digest.rb +22 -0
  165. data/lib/active_support/duration/iso8601_parser.rb +9 -9
  166. data/lib/active_support/duration/iso8601_serializer.rb +29 -15
  167. data/lib/active_support/duration.rb +158 -72
  168. data/lib/active_support/encrypted_configuration.rb +56 -0
  169. data/lib/active_support/encrypted_file.rb +129 -0
  170. data/lib/active_support/environment_inquirer.rb +20 -0
  171. data/lib/active_support/error_reporter.rb +117 -0
  172. data/lib/active_support/evented_file_update_checker.rb +87 -122
  173. data/lib/active_support/execution_context/test_helper.rb +13 -0
  174. data/lib/active_support/execution_context.rb +53 -0
  175. data/lib/active_support/execution_wrapper.rb +46 -21
  176. data/lib/active_support/executor/test_helper.rb +7 -0
  177. data/lib/active_support/executor.rb +2 -0
  178. data/lib/active_support/file_update_checker.rb +2 -1
  179. data/lib/active_support/fork_tracker.rb +71 -0
  180. data/lib/active_support/gem_version.rb +7 -5
  181. data/lib/active_support/gzip.rb +2 -0
  182. data/lib/active_support/hash_with_indifferent_access.rb +126 -42
  183. data/lib/active_support/html_safe_translation.rb +43 -0
  184. data/lib/active_support/i18n.rb +5 -1
  185. data/lib/active_support/i18n_railtie.rb +19 -14
  186. data/lib/active_support/inflections.rb +2 -0
  187. data/lib/active_support/inflector/inflections.rb +41 -14
  188. data/lib/active_support/inflector/methods.rb +73 -87
  189. data/lib/active_support/inflector/transliterate.rb +56 -18
  190. data/lib/active_support/inflector.rb +2 -0
  191. data/lib/active_support/isolated_execution_state.rb +72 -0
  192. data/lib/active_support/json/decoding.rb +27 -26
  193. data/lib/active_support/json/encoding.rb +16 -6
  194. data/lib/active_support/json.rb +2 -0
  195. data/lib/active_support/key_generator.rb +25 -38
  196. data/lib/active_support/lazy_load_hooks.rb +35 -6
  197. data/lib/active_support/locale/en.rb +33 -0
  198. data/lib/active_support/locale/en.yml +8 -4
  199. data/lib/active_support/log_subscriber/test_helper.rb +4 -2
  200. data/lib/active_support/log_subscriber.rb +54 -13
  201. data/lib/active_support/logger.rb +4 -17
  202. data/lib/active_support/logger_silence.rb +13 -20
  203. data/lib/active_support/logger_thread_safe_level.rb +48 -10
  204. data/lib/active_support/message_encryptor.rb +111 -37
  205. data/lib/active_support/message_verifier.rb +124 -21
  206. data/lib/active_support/messages/metadata.rb +80 -0
  207. data/lib/active_support/messages/rotation_configuration.rb +23 -0
  208. data/lib/active_support/messages/rotator.rb +57 -0
  209. data/lib/active_support/multibyte/chars.rb +19 -76
  210. data/lib/active_support/multibyte/unicode.rb +9 -331
  211. data/lib/active_support/multibyte.rb +3 -1
  212. data/lib/active_support/notifications/fanout.rb +165 -37
  213. data/lib/active_support/notifications/instrumenter.rb +92 -11
  214. data/lib/active_support/notifications.rb +96 -30
  215. data/lib/active_support/number_helper/number_converter.rb +8 -9
  216. data/lib/active_support/number_helper/number_to_currency_converter.rb +14 -12
  217. data/lib/active_support/number_helper/number_to_delimited_converter.rb +6 -3
  218. data/lib/active_support/number_helper/number_to_human_converter.rb +6 -3
  219. data/lib/active_support/number_helper/number_to_human_size_converter.rb +7 -4
  220. data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
  221. data/lib/active_support/number_helper/number_to_phone_converter.rb +6 -3
  222. data/lib/active_support/number_helper/number_to_rounded_converter.rb +14 -27
  223. data/lib/active_support/number_helper/rounding_helper.rb +16 -34
  224. data/lib/active_support/number_helper.rb +38 -12
  225. data/lib/active_support/option_merger.rb +19 -6
  226. data/lib/active_support/ordered_hash.rb +4 -2
  227. data/lib/active_support/ordered_options.rb +18 -6
  228. data/lib/active_support/parameter_filter.rb +138 -0
  229. data/lib/active_support/per_thread_registry.rb +8 -1
  230. data/lib/active_support/proxy_object.rb +2 -0
  231. data/lib/active_support/rails.rb +3 -10
  232. data/lib/active_support/railtie.rb +112 -11
  233. data/lib/active_support/reloader.rb +12 -11
  234. data/lib/active_support/rescuable.rb +19 -18
  235. data/lib/active_support/ruby_features.rb +7 -0
  236. data/lib/active_support/secure_compare_rotator.rb +51 -0
  237. data/lib/active_support/security_utils.rb +26 -15
  238. data/lib/active_support/string_inquirer.rb +4 -3
  239. data/lib/active_support/subscriber.rb +81 -42
  240. data/lib/active_support/tagged_logging.rb +45 -9
  241. data/lib/active_support/test_case.rb +86 -2
  242. data/lib/active_support/testing/assertions.rb +89 -21
  243. data/lib/active_support/testing/autorun.rb +2 -0
  244. data/lib/active_support/testing/constant_lookup.rb +2 -0
  245. data/lib/active_support/testing/declarative.rb +2 -0
  246. data/lib/active_support/testing/deprecation.rb +54 -2
  247. data/lib/active_support/testing/file_fixtures.rb +4 -0
  248. data/lib/active_support/testing/isolation.rb +6 -4
  249. data/lib/active_support/testing/method_call_assertions.rb +34 -5
  250. data/lib/active_support/testing/parallelization/server.rb +82 -0
  251. data/lib/active_support/testing/parallelization/worker.rb +103 -0
  252. data/lib/active_support/testing/parallelization.rb +55 -0
  253. data/lib/active_support/testing/parallelize_executor.rb +76 -0
  254. data/lib/active_support/testing/setup_and_teardown.rb +12 -7
  255. data/lib/active_support/testing/stream.rb +6 -7
  256. data/lib/active_support/testing/tagged_logging.rb +3 -1
  257. data/lib/active_support/testing/time_helpers.rb +91 -15
  258. data/lib/active_support/time.rb +2 -0
  259. data/lib/active_support/time_with_zone.rb +168 -56
  260. data/lib/active_support/values/time_zone.rb +85 -37
  261. data/lib/active_support/version.rb +3 -1
  262. data/lib/active_support/xml_mini/jdom.rb +6 -5
  263. data/lib/active_support/xml_mini/libxml.rb +9 -7
  264. data/lib/active_support/xml_mini/libxmlsax.rb +7 -5
  265. data/lib/active_support/xml_mini/nokogiri.rb +8 -6
  266. data/lib/active_support/xml_mini/nokogirisax.rb +6 -4
  267. data/lib/active_support/xml_mini/rexml.rb +13 -4
  268. data/lib/active_support/xml_mini.rb +10 -15
  269. data/lib/active_support.rb +30 -9
  270. metadata +76 -35
  271. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
  272. data/lib/active_support/core_ext/hash/compact.rb +0 -27
  273. data/lib/active_support/core_ext/hash/transform_values.rb +0 -30
  274. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  275. data/lib/active_support/core_ext/marshal.rb +0 -22
  276. data/lib/active_support/core_ext/module/reachable.rb +0 -8
  277. data/lib/active_support/core_ext/numeric/inquiry.rb +0 -26
  278. data/lib/active_support/core_ext/range/include_range.rb +0 -23
  279. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,31 +1,41 @@
1
- module ActiveSupport::RangeWithFormat
2
- RANGE_FORMATS = {
3
- db: Proc.new { |start, stop| "BETWEEN '#{start.to_s(:db)}' AND '#{stop.to_s(:db)}'" }
4
- }
1
+ # frozen_string_literal: true
5
2
 
6
- # Convert range to a formatted string. See RANGE_FORMATS for predefined formats.
7
- #
8
- # range = (1..100) # => 1..100
9
- #
10
- # range.to_s # => "1..100"
11
- # range.to_s(:db) # => "BETWEEN '1' AND '100'"
12
- #
13
- # == Adding your own range formats to to_s
14
- # You can add your own formats to the Range::RANGE_FORMATS hash.
15
- # Use the format name as the hash key and a Proc instance.
16
- #
17
- # # config/initializers/range_formats.rb
18
- # Range::RANGE_FORMATS[:short] = ->(start, stop) { "Between #{start.to_s(:db)} and #{stop.to_s(:db)}" }
19
- def to_s(format = :default)
20
- if formatter = RANGE_FORMATS[format]
21
- formatter.call(first, last)
22
- else
23
- super()
3
+ module ActiveSupport
4
+ module RangeWithFormat
5
+ RANGE_FORMATS = {
6
+ db: -> (start, stop) do
7
+ case start
8
+ when String then "BETWEEN '#{start}' AND '#{stop}'"
9
+ else
10
+ "BETWEEN '#{start.to_fs(:db)}' AND '#{stop.to_fs(:db)}'"
11
+ end
12
+ end
13
+ }
14
+
15
+ # Convert range to a formatted string. See RANGE_FORMATS for predefined formats.
16
+ #
17
+ # This method is aliased to <tt>to_formatted_s</tt>.
18
+ #
19
+ # range = (1..100) # => 1..100
20
+ #
21
+ # range.to_s # => "1..100"
22
+ # range.to_fs(:db) # => "BETWEEN '1' AND '100'"
23
+ #
24
+ # == Adding your own range formats to to_s
25
+ # You can add your own formats to the Range::RANGE_FORMATS hash.
26
+ # Use the format name as the hash key and a Proc instance.
27
+ #
28
+ # # config/initializers/range_formats.rb
29
+ # Range::RANGE_FORMATS[:short] = ->(start, stop) { "Between #{start.to_fs(:db)} and #{stop.to_fs(:db)}" }
30
+ def to_fs(format = :default)
31
+ if formatter = RANGE_FORMATS[format]
32
+ formatter.call(first, last)
33
+ else
34
+ to_s
35
+ end
24
36
  end
37
+ alias_method :to_formatted_s, :to_fs
25
38
  end
26
-
27
- alias_method :to_default_s, :to_s
28
- alias_method :to_formatted_s, :to_s
29
39
  end
30
40
 
31
41
  Range.prepend(ActiveSupport::RangeWithFormat)
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ module DeprecatedRangeWithFormat # :nodoc:
5
+ NOT_SET = Object.new # :nodoc:
6
+ def to_s(format = NOT_SET)
7
+ if formatter = RangeWithFormat::RANGE_FORMATS[format]
8
+ ActiveSupport::Deprecation.warn(
9
+ "Range#to_s(#{format.inspect}) is deprecated. Please use Range#to_fs(#{format.inspect}) instead."
10
+ )
11
+ formatter.call(first, last)
12
+ elsif format == NOT_SET
13
+ super()
14
+ else
15
+ ActiveSupport::Deprecation.warn(
16
+ "Range#to_s(#{format.inspect}) is deprecated. Please use Range#to_fs(#{format.inspect}) instead."
17
+ )
18
+ super()
19
+ end
20
+ end
21
+ alias_method :to_default_s, :to_s
22
+ deprecate :to_default_s
23
+ end
24
+ end
25
+
26
+ Range.prepend(ActiveSupport::DeprecatedRangeWithFormat)
@@ -1,5 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/time_with_zone"
4
+
1
5
  module ActiveSupport
2
- module EachTimeWithZone #:nodoc:
6
+ module EachTimeWithZone # :nodoc:
3
7
  def each(&block)
4
8
  ensure_iteration_allowed
5
9
  super
@@ -11,9 +15,8 @@ module ActiveSupport
11
15
  end
12
16
 
13
17
  private
14
-
15
18
  def ensure_iteration_allowed
16
- raise TypeError, "can't iterate from #{first.class}" if first.is_a?(Time)
19
+ raise TypeError, "can't iterate from #{first.class}" if first.is_a?(TimeWithZone)
17
20
  end
18
21
  end
19
22
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ # frozen_string_literal: true
4
+
5
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
6
+ `active_support/core_ext/range/include_time_with_zone` is deprecated and will be removed in Rails 7.1.
7
+ MSG
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Range
2
4
  # Compare two ranges and see if they overlap each other
3
5
  # (1..5).overlaps?(4..6) # => true
4
6
  # (1..5).overlaps?(7..9) # => false
5
7
  def overlaps?(other)
6
- cover?(other.first) || other.cover?(first)
8
+ other.begin == self.begin || cover?(other.begin) || other.cover?(self.begin)
7
9
  end
8
10
  end
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/range/conversions"
2
- require "active_support/core_ext/range/include_range"
4
+ require "active_support/core_ext/range/deprecated_conversions" unless ENV["RAILS_DISABLE_DEPRECATED_TO_S_CONVERSION"]
5
+ require "active_support/core_ext/range/compare_range"
3
6
  require "active_support/core_ext/range/overlaps"
4
7
  require "active_support/core_ext/range/each"
@@ -1,9 +1,14 @@
1
- class Regexp #:nodoc:
1
+ # frozen_string_literal: true
2
+
3
+ class Regexp
4
+ # Returns +true+ if the regexp has the multiline flag set.
5
+ #
6
+ # (/./).multiline? # => false
7
+ # (/./m).multiline? # => true
8
+ #
9
+ # Regexp.new(".").multiline? # => false
10
+ # Regexp.new(".", Regexp::MULTILINE).multiline? # => true
2
11
  def multiline?
3
12
  options & MULTILINE == MULTILINE
4
13
  end
5
-
6
- def match?(string, pos = 0)
7
- !!match(string, pos)
8
- end unless //.respond_to?(:match?)
9
14
  end
@@ -1,18 +1,21 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "securerandom"
2
4
 
3
5
  module SecureRandom
4
6
  BASE58_ALPHABET = ("0".."9").to_a + ("A".."Z").to_a + ("a".."z").to_a - ["0", "O", "I", "l"]
7
+ BASE36_ALPHABET = ("0".."9").to_a + ("a".."z").to_a
8
+
5
9
  # SecureRandom.base58 generates a random base58 string.
6
10
  #
7
- # The argument _n_ specifies the length, of the random string to be generated.
11
+ # The argument _n_ specifies the length of the random string to be generated.
8
12
  #
9
13
  # If _n_ is not specified or is +nil+, 16 is assumed. It may be larger in the future.
10
14
  #
11
- # The result may contain alphanumeric characters except 0, O, I and l
15
+ # The result may contain alphanumeric characters except 0, O, I, and l.
12
16
  #
13
17
  # p SecureRandom.base58 # => "4kUgL2pdQMSCQtjE"
14
18
  # p SecureRandom.base58(24) # => "77TMHrHJFvFDwodq8w7Ev2m7"
15
- #
16
19
  def self.base58(n = 16)
17
20
  SecureRandom.random_bytes(n).unpack("C*").map do |byte|
18
21
  idx = byte % 64
@@ -20,4 +23,23 @@ module SecureRandom
20
23
  BASE58_ALPHABET[idx]
21
24
  end.join
22
25
  end
26
+
27
+ # SecureRandom.base36 generates a random base36 string in lowercase.
28
+ #
29
+ # The argument _n_ specifies the length of the random string to be generated.
30
+ #
31
+ # If _n_ is not specified or is +nil+, 16 is assumed. It may be larger in the future.
32
+ # This method can be used over +base58+ if a deterministic case key is necessary.
33
+ #
34
+ # The result will contain alphanumeric characters in lowercase.
35
+ #
36
+ # p SecureRandom.base36 # => "4kugl2pdqmscqtje"
37
+ # p SecureRandom.base36(24) # => "77tmhrhjfvfdwodq8w7ev2m7"
38
+ def self.base36(n = 16)
39
+ SecureRandom.random_bytes(n).unpack("C*").map do |byte|
40
+ idx = byte % 64
41
+ idx = SecureRandom.random_number(36) if idx >= 36
42
+ BASE36_ALPHABET[idx]
43
+ end.join
44
+ end
23
45
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class String
2
4
  # If you pass a single integer, returns a substring of one character at that
3
5
  # position. The first character of the string is at position 0, the next at
@@ -42,7 +44,7 @@ class String
42
44
  # str.from(0).to(-1) # => "hello"
43
45
  # str.from(1).to(-2) # => "ell"
44
46
  def from(position)
45
- self[position..-1]
47
+ self[position, length]
46
48
  end
47
49
 
48
50
  # Returns a substring from the beginning of the string to the given position.
@@ -59,7 +61,8 @@ class String
59
61
  # str.from(0).to(-1) # => "hello"
60
62
  # str.from(1).to(-2) # => "ell"
61
63
  def to(position)
62
- self[0..position]
64
+ position += size if position < 0
65
+ self[0, position + 1] || +""
63
66
  end
64
67
 
65
68
  # Returns the first character. If a limit is supplied, returns a substring
@@ -73,13 +76,7 @@ class String
73
76
  # str.first(0) # => ""
74
77
  # str.first(6) # => "hello"
75
78
  def first(limit = 1)
76
- if limit == 0
77
- ""
78
- elsif limit >= size
79
- dup
80
- else
81
- to(limit - 1)
82
- end
79
+ self[0, limit] || raise(ArgumentError, "negative limit")
83
80
  end
84
81
 
85
82
  # Returns the last character of the string. If a limit is supplied, returns a substring
@@ -93,12 +90,6 @@ class String
93
90
  # str.last(0) # => ""
94
91
  # str.last(6) # => "hello"
95
92
  def last(limit = 1)
96
- if limit == 0
97
- ""
98
- elsif limit >= size
99
- dup
100
- else
101
- from(-limit)
102
- end
93
+ self[[length - limit, 0].max, limit] || raise(ArgumentError, "negative limit")
103
94
  end
104
95
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class String
2
4
  # Enables more predictable duck-typing on String-like classes. See <tt>Object#acts_like?</tt>.
3
5
  def acts_like_string?
@@ -1,12 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "date"
2
4
  require "active_support/core_ext/time/calculations"
3
5
 
4
6
  class String
5
7
  # Converts a string to a Time value.
6
- # The +form+ can be either :utc or :local (default :local).
8
+ # The +form+ can be either +:utc+ or +:local+ (default +:local+).
7
9
  #
8
10
  # The time is parsed using Time.parse method.
9
- # If +form+ is :local, then the time is in the system timezone.
11
+ # If +form+ is +:local+, then the time is in the system timezone.
10
12
  # If the date part is missing then the current date is used and if
11
13
  # the time part is missing then it is assumed to be 00:00:00.
12
14
  #
@@ -16,6 +18,7 @@ class String
16
18
  # "2012-12-13T06:12".to_time # => 2012-12-13 06:12:00 +0100
17
19
  # "2012-12-13T06:12".to_time(:utc) # => 2012-12-13 06:12:00 UTC
18
20
  # "12/13/2012".to_time # => ArgumentError: argument out of range
21
+ # "1604326192".to_time # => ArgumentError: argument out of range
19
22
  def to_time(form = :local)
20
23
  parts = Date._parse(self, false)
21
24
  used_keys = %i(year mon mday hour min sec sec_fraction offset)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class String
2
4
  # The inverse of <tt>String#include?</tt>. Returns true if the string
3
5
  # does not include the other string.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class String
2
4
  # Returns the string, first removing all whitespace on both ends of
3
5
  # the string, and then changing remaining consecutive whitespace
@@ -73,7 +75,48 @@ class String
73
75
  length_with_room_for_omission
74
76
  end
75
77
 
76
- "#{self[0, stop]}#{omission}"
78
+ +"#{self[0, stop]}#{omission}"
79
+ end
80
+
81
+ # Truncates +text+ to at most <tt>bytesize</tt> bytes in length without
82
+ # breaking string encoding by splitting multibyte characters or breaking
83
+ # grapheme clusters ("perceptual characters") by truncating at combining
84
+ # characters.
85
+ #
86
+ # >> "🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪".size
87
+ # => 20
88
+ # >> "🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪".bytesize
89
+ # => 80
90
+ # >> "🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪".truncate_bytes(20)
91
+ # => "🔪🔪🔪🔪…"
92
+ #
93
+ # The truncated text ends with the <tt>:omission</tt> string, defaulting
94
+ # to "…", for a total length not exceeding <tt>bytesize</tt>.
95
+ def truncate_bytes(truncate_at, omission: "…")
96
+ omission ||= ""
97
+
98
+ case
99
+ when bytesize <= truncate_at
100
+ dup
101
+ when omission.bytesize > truncate_at
102
+ raise ArgumentError, "Omission #{omission.inspect} is #{omission.bytesize}, larger than the truncation length of #{truncate_at} bytes"
103
+ when omission.bytesize == truncate_at
104
+ omission.dup
105
+ else
106
+ self.class.new.tap do |cut|
107
+ cut_at = truncate_at - omission.bytesize
108
+
109
+ each_grapheme_cluster do |grapheme|
110
+ if cut.bytesize + grapheme.bytesize <= cut_at
111
+ cut << grapheme
112
+ else
113
+ break
114
+ end
115
+ end
116
+
117
+ cut << omission
118
+ end
119
+ end
77
120
  end
78
121
 
79
122
  # Truncates a given +text+ after a given number of words (<tt>words_count</tt>):
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class String
2
4
  # Same as +indent+, except it indents the receiver in-place.
3
5
  #
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/inflector/methods"
2
4
  require "active_support/inflector/transliterate"
3
5
 
@@ -28,6 +30,8 @@ class String
28
30
  # 'apple'.pluralize(2) # => "apples"
29
31
  # 'ley'.pluralize(:es) # => "leyes"
30
32
  # 'ley'.pluralize(1, :es) # => "ley"
33
+ #
34
+ # See ActiveSupport::Inflector.pluralize.
31
35
  def pluralize(count = nil, locale = :en)
32
36
  locale = count if count.is_a?(Symbol)
33
37
  if count == 1
@@ -51,28 +55,34 @@ class String
51
55
  # 'the blue mailmen'.singularize # => "the blue mailman"
52
56
  # 'CamelOctopi'.singularize # => "CamelOctopus"
53
57
  # 'leyes'.singularize(:es) # => "ley"
58
+ #
59
+ # See ActiveSupport::Inflector.singularize.
54
60
  def singularize(locale = :en)
55
61
  ActiveSupport::Inflector.singularize(self, locale)
56
62
  end
57
63
 
58
64
  # +constantize+ tries to find a declared constant with the name specified
59
65
  # in the string. It raises a NameError when the name is not in CamelCase
60
- # or is not initialized. See ActiveSupport::Inflector.constantize
66
+ # or is not initialized.
61
67
  #
62
68
  # 'Module'.constantize # => Module
63
69
  # 'Class'.constantize # => Class
64
70
  # 'blargle'.constantize # => NameError: wrong constant name blargle
71
+ #
72
+ # See ActiveSupport::Inflector.constantize.
65
73
  def constantize
66
74
  ActiveSupport::Inflector.constantize(self)
67
75
  end
68
76
 
69
77
  # +safe_constantize+ tries to find a declared constant with the name specified
70
78
  # in the string. It returns +nil+ when the name is not in CamelCase
71
- # or is not initialized. See ActiveSupport::Inflector.safe_constantize
79
+ # or is not initialized.
72
80
  #
73
81
  # 'Module'.safe_constantize # => Module
74
82
  # 'Class'.safe_constantize # => Class
75
83
  # 'blargle'.safe_constantize # => nil
84
+ #
85
+ # See ActiveSupport::Inflector.safe_constantize.
76
86
  def safe_constantize
77
87
  ActiveSupport::Inflector.safe_constantize(self)
78
88
  end
@@ -86,12 +96,18 @@ class String
86
96
  # 'active_record'.camelize(:lower) # => "activeRecord"
87
97
  # 'active_record/errors'.camelize # => "ActiveRecord::Errors"
88
98
  # 'active_record/errors'.camelize(:lower) # => "activeRecord::Errors"
99
+ #
100
+ # +camelize+ is also aliased as +camelcase+.
101
+ #
102
+ # See ActiveSupport::Inflector.camelize.
89
103
  def camelize(first_letter = :upper)
90
104
  case first_letter
91
105
  when :upper
92
106
  ActiveSupport::Inflector.camelize(self, true)
93
107
  when :lower
94
108
  ActiveSupport::Inflector.camelize(self, false)
109
+ else
110
+ raise ArgumentError, "Invalid option, use either :upper or :lower."
95
111
  end
96
112
  end
97
113
  alias_method :camelcase, :camelize
@@ -100,12 +116,19 @@ class String
100
116
  # a nicer looking title. +titleize+ is meant for creating pretty output. It is not
101
117
  # used in the Rails internals.
102
118
  #
119
+ # The trailing '_id','Id'.. can be kept and capitalized by setting the
120
+ # optional parameter +keep_id_suffix+ to true.
121
+ # By default, this parameter is false.
122
+ #
123
+ # 'man from the boondocks'.titleize # => "Man From The Boondocks"
124
+ # 'x-men: the last stand'.titleize # => "X Men: The Last Stand"
125
+ # 'string_ending_with_id'.titleize(keep_id_suffix: true) # => "String Ending With Id"
126
+ #
103
127
  # +titleize+ is also aliased as +titlecase+.
104
128
  #
105
- # 'man from the boondocks'.titleize # => "Man From The Boondocks"
106
- # 'x-men: the last stand'.titleize # => "X Men: The Last Stand"
107
- def titleize
108
- ActiveSupport::Inflector.titleize(self)
129
+ # See ActiveSupport::Inflector.titleize.
130
+ def titleize(keep_id_suffix: false)
131
+ ActiveSupport::Inflector.titleize(self, keep_id_suffix: keep_id_suffix)
109
132
  end
110
133
  alias_method :titlecase, :titleize
111
134
 
@@ -115,6 +138,8 @@ class String
115
138
  #
116
139
  # 'ActiveModel'.underscore # => "active_model"
117
140
  # 'ActiveModel::Errors'.underscore # => "active_model/errors"
141
+ #
142
+ # See ActiveSupport::Inflector.underscore.
118
143
  def underscore
119
144
  ActiveSupport::Inflector.underscore(self)
120
145
  end
@@ -122,6 +147,8 @@ class String
122
147
  # Replaces underscores with dashes in the string.
123
148
  #
124
149
  # 'puni_puni'.dasherize # => "puni-puni"
150
+ #
151
+ # See ActiveSupport::Inflector.dasherize.
125
152
  def dasherize
126
153
  ActiveSupport::Inflector.dasherize(self)
127
154
  end
@@ -133,6 +160,8 @@ class String
133
160
  # '::Inflections'.demodulize # => "Inflections"
134
161
  # ''.demodulize # => ''
135
162
  #
163
+ # See ActiveSupport::Inflector.demodulize.
164
+ #
136
165
  # See also +deconstantize+.
137
166
  def demodulize
138
167
  ActiveSupport::Inflector.demodulize(self)
@@ -146,6 +175,8 @@ class String
146
175
  # '::String'.deconstantize # => ""
147
176
  # ''.deconstantize # => ""
148
177
  #
178
+ # See ActiveSupport::Inflector.deconstantize.
179
+ #
149
180
  # See also +demodulize+.
150
181
  def deconstantize
151
182
  ActiveSupport::Inflector.deconstantize(self)
@@ -153,6 +184,11 @@ class String
153
184
 
154
185
  # Replaces special characters in a string so that it may be used as part of a 'pretty' URL.
155
186
  #
187
+ # If the optional parameter +locale+ is specified,
188
+ # the word will be parameterized as a word of that language.
189
+ # By default, this parameter is set to <tt>nil</tt> and it will use
190
+ # the configured <tt>I18n.locale</tt>.
191
+ #
156
192
  # class Person
157
193
  # def to_param
158
194
  # "#{id}-#{name.parameterize}"
@@ -165,7 +201,7 @@ class String
165
201
  # <%= link_to(@person.name, person_path) %>
166
202
  # # => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>
167
203
  #
168
- # To preserve the case of the characters in a string, use the `preserve_case` argument.
204
+ # To preserve the case of the characters in a string, use the +preserve_case+ argument.
169
205
  #
170
206
  # class Person
171
207
  # def to_param
@@ -178,8 +214,10 @@ class String
178
214
  #
179
215
  # <%= link_to(@person.name, person_path) %>
180
216
  # # => <a href="/person/1-Donald-E-Knuth">Donald E. Knuth</a>
181
- def parameterize(separator: "-", preserve_case: false)
182
- ActiveSupport::Inflector.parameterize(self, separator: separator, preserve_case: preserve_case)
217
+ #
218
+ # See ActiveSupport::Inflector.parameterize.
219
+ def parameterize(separator: "-", preserve_case: false, locale: nil)
220
+ ActiveSupport::Inflector.parameterize(self, separator: separator, preserve_case: preserve_case, locale: locale)
183
221
  end
184
222
 
185
223
  # Creates the name of a table like Rails does for models to table names. This method
@@ -188,6 +226,8 @@ class String
188
226
  # 'RawScaledScorer'.tableize # => "raw_scaled_scorers"
189
227
  # 'ham_and_egg'.tableize # => "ham_and_eggs"
190
228
  # 'fancyCategory'.tableize # => "fancy_categories"
229
+ #
230
+ # See ActiveSupport::Inflector.tableize.
191
231
  def tableize
192
232
  ActiveSupport::Inflector.tableize(self)
193
233
  end
@@ -198,11 +238,13 @@ class String
198
238
  #
199
239
  # 'ham_and_eggs'.classify # => "HamAndEgg"
200
240
  # 'posts'.classify # => "Post"
241
+ #
242
+ # See ActiveSupport::Inflector.classify.
201
243
  def classify
202
244
  ActiveSupport::Inflector.classify(self)
203
245
  end
204
246
 
205
- # Capitalizes the first word, turns underscores into spaces, and strips a
247
+ # Capitalizes the first word, turns underscores into spaces, and (by default)strips a
206
248
  # trailing '_id' if present.
207
249
  # Like +titleize+, this is meant for creating pretty output.
208
250
  #
@@ -210,12 +252,19 @@ class String
210
252
  # optional parameter +capitalize+ to false.
211
253
  # By default, this parameter is true.
212
254
  #
213
- # 'employee_salary'.humanize # => "Employee salary"
214
- # 'author_id'.humanize # => "Author"
215
- # 'author_id'.humanize(capitalize: false) # => "author"
216
- # '_id'.humanize # => "Id"
217
- def humanize(options = {})
218
- ActiveSupport::Inflector.humanize(self, options)
255
+ # The trailing '_id' can be kept and capitalized by setting the
256
+ # optional parameter +keep_id_suffix+ to true.
257
+ # By default, this parameter is false.
258
+ #
259
+ # 'employee_salary'.humanize # => "Employee salary"
260
+ # 'author_id'.humanize # => "Author"
261
+ # 'author_id'.humanize(capitalize: false) # => "author"
262
+ # '_id'.humanize # => "Id"
263
+ # 'author_id'.humanize(keep_id_suffix: true) # => "Author id"
264
+ #
265
+ # See ActiveSupport::Inflector.humanize.
266
+ def humanize(capitalize: true, keep_id_suffix: false)
267
+ ActiveSupport::Inflector.humanize(self, capitalize: capitalize, keep_id_suffix: keep_id_suffix)
219
268
  end
220
269
 
221
270
  # Converts just the first character to uppercase.
@@ -223,6 +272,8 @@ class String
223
272
  # 'what a Lovely Day'.upcase_first # => "What a Lovely Day"
224
273
  # 'w'.upcase_first # => "W"
225
274
  # ''.upcase_first # => ""
275
+ #
276
+ # See ActiveSupport::Inflector.upcase_first.
226
277
  def upcase_first
227
278
  ActiveSupport::Inflector.upcase_first(self)
228
279
  end
@@ -234,6 +285,8 @@ class String
234
285
  # 'Message'.foreign_key # => "message_id"
235
286
  # 'Message'.foreign_key(false) # => "messageid"
236
287
  # 'Admin::Post'.foreign_key # => "post_id"
288
+ #
289
+ # See ActiveSupport::Inflector.foreign_key.
237
290
  def foreign_key(separate_class_name_and_id_with_underscore = true)
238
291
  ActiveSupport::Inflector.foreign_key(self, separate_class_name_and_id_with_underscore)
239
292
  end
@@ -1,7 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/string_inquirer"
4
+ require "active_support/environment_inquirer"
2
5
 
3
6
  class String
4
- # Wraps the current string in the <tt>ActiveSupport::StringInquirer</tt> class,
7
+ # Wraps the current string in the ActiveSupport::StringInquirer class,
5
8
  # which gives you a prettier way to test for equality.
6
9
  #
7
10
  # env = 'production'.inquiry
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/multibyte"
2
4
 
3
5
  class String
@@ -9,11 +11,14 @@ class String
9
11
  # encapsulates the original string. A Unicode safe version of all the String methods are defined on this proxy
10
12
  # class. If the proxy class doesn't respond to a certain method, it's forwarded to the encapsulated string.
11
13
  #
12
- # >> "lj".upcase
13
- # => "lj"
14
14
  # >> "lj".mb_chars.upcase.to_s
15
15
  # => "LJ"
16
16
  #
17
+ # NOTE: Ruby 2.4 and later support native Unicode case mappings:
18
+ #
19
+ # >> "lj".upcase
20
+ # => "LJ"
21
+ #
17
22
  # == Method chaining
18
23
  #
19
24
  # All the methods on the Chars proxy which normally return a string will return a Chars object. This allows
@@ -42,9 +47,9 @@ class String
42
47
  # iso_str.is_utf8? # => false
43
48
  def is_utf8?
44
49
  case encoding
45
- when Encoding::UTF_8
50
+ when Encoding::UTF_8, Encoding::US_ASCII
46
51
  valid_encoding?
47
- when Encoding::ASCII_8BIT, Encoding::US_ASCII
52
+ when Encoding::ASCII_8BIT
48
53
  dup.force_encoding(Encoding::UTF_8).valid_encoding?
49
54
  else
50
55
  false