activesupport 6.1.7.2 → 7.0.6

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activesupport might be problematic. Click here for more details.

Files changed (183) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +272 -501
  3. data/README.rdoc +2 -2
  4. data/lib/active_support/actionable_error.rb +1 -1
  5. data/lib/active_support/array_inquirer.rb +0 -2
  6. data/lib/active_support/backtrace_cleaner.rb +2 -2
  7. data/lib/active_support/benchmarkable.rb +2 -2
  8. data/lib/active_support/cache/file_store.rb +15 -9
  9. data/lib/active_support/cache/mem_cache_store.rb +148 -37
  10. data/lib/active_support/cache/memory_store.rb +24 -16
  11. data/lib/active_support/cache/null_store.rb +10 -2
  12. data/lib/active_support/cache/redis_cache_store.rb +59 -78
  13. data/lib/active_support/cache/strategy/local_cache.rb +38 -61
  14. data/lib/active_support/cache.rb +299 -147
  15. data/lib/active_support/callbacks.rb +184 -85
  16. data/lib/active_support/code_generator.rb +65 -0
  17. data/lib/active_support/concern.rb +5 -5
  18. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +2 -4
  19. data/lib/active_support/concurrency/share_lock.rb +2 -2
  20. data/lib/active_support/configurable.rb +8 -5
  21. data/lib/active_support/configuration_file.rb +1 -1
  22. data/lib/active_support/core_ext/array/access.rb +1 -5
  23. data/lib/active_support/core_ext/array/conversions.rb +13 -12
  24. data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
  25. data/lib/active_support/core_ext/array/grouping.rb +6 -6
  26. data/lib/active_support/core_ext/array/inquiry.rb +2 -2
  27. data/lib/active_support/core_ext/array.rb +1 -0
  28. data/lib/active_support/core_ext/big_decimal/conversions.rb +1 -1
  29. data/lib/active_support/core_ext/class/subclasses.rb +25 -17
  30. data/lib/active_support/core_ext/date/blank.rb +1 -1
  31. data/lib/active_support/core_ext/date/calculations.rb +24 -9
  32. data/lib/active_support/core_ext/date/conversions.rb +14 -14
  33. data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
  34. data/lib/active_support/core_ext/date.rb +1 -0
  35. data/lib/active_support/core_ext/date_and_time/calculations.rb +4 -4
  36. data/lib/active_support/core_ext/date_and_time/compatibility.rb +1 -1
  37. data/lib/active_support/core_ext/date_time/blank.rb +1 -1
  38. data/lib/active_support/core_ext/date_time/calculations.rb +4 -0
  39. data/lib/active_support/core_ext/date_time/conversions.rb +13 -13
  40. data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
  41. data/lib/active_support/core_ext/date_time.rb +1 -0
  42. data/lib/active_support/core_ext/digest/uuid.rb +39 -14
  43. data/lib/active_support/core_ext/enumerable.rb +106 -37
  44. data/lib/active_support/core_ext/file/atomic.rb +3 -1
  45. data/lib/active_support/core_ext/hash/conversions.rb +0 -1
  46. data/lib/active_support/core_ext/hash/deep_transform_values.rb +3 -3
  47. data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
  48. data/lib/active_support/core_ext/hash/keys.rb +4 -4
  49. data/lib/active_support/core_ext/integer/inflections.rb +12 -12
  50. data/lib/active_support/core_ext/kernel/reporting.rb +4 -4
  51. data/lib/active_support/core_ext/kernel/singleton_class.rb +1 -1
  52. data/lib/active_support/core_ext/module/attribute_accessors.rb +2 -0
  53. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +19 -10
  54. data/lib/active_support/core_ext/module/delegation.rb +2 -8
  55. data/lib/active_support/core_ext/name_error.rb +2 -8
  56. data/lib/active_support/core_ext/numeric/conversions.rb +80 -77
  57. data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
  58. data/lib/active_support/core_ext/numeric.rb +1 -0
  59. data/lib/active_support/core_ext/object/acts_like.rb +29 -5
  60. data/lib/active_support/core_ext/object/blank.rb +2 -2
  61. data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
  62. data/lib/active_support/core_ext/object/duplicable.rb +15 -4
  63. data/lib/active_support/core_ext/object/json.rb +30 -25
  64. data/lib/active_support/core_ext/object/to_query.rb +2 -4
  65. data/lib/active_support/core_ext/object/try.rb +20 -20
  66. data/lib/active_support/core_ext/object/with_options.rb +21 -2
  67. data/lib/active_support/core_ext/pathname/existence.rb +21 -0
  68. data/lib/active_support/core_ext/pathname.rb +3 -0
  69. data/lib/active_support/core_ext/range/compare_range.rb +0 -25
  70. data/lib/active_support/core_ext/range/conversions.rb +8 -8
  71. data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
  72. data/lib/active_support/core_ext/range/each.rb +1 -1
  73. data/lib/active_support/core_ext/range/include_time_with_zone.rb +3 -26
  74. data/lib/active_support/core_ext/range/overlaps.rb +1 -1
  75. data/lib/active_support/core_ext/range.rb +1 -1
  76. data/lib/active_support/core_ext/securerandom.rb +1 -1
  77. data/lib/active_support/core_ext/string/conversions.rb +2 -2
  78. data/lib/active_support/core_ext/string/filters.rb +1 -1
  79. data/lib/active_support/core_ext/string/inflections.rb +1 -5
  80. data/lib/active_support/core_ext/string/inquiry.rb +1 -1
  81. data/lib/active_support/core_ext/string/output_safety.rb +66 -38
  82. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +0 -8
  83. data/lib/active_support/core_ext/time/calculations.rb +11 -8
  84. data/lib/active_support/core_ext/time/conversions.rb +13 -12
  85. data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
  86. data/lib/active_support/core_ext/time/zones.rb +10 -26
  87. data/lib/active_support/core_ext/time.rb +1 -0
  88. data/lib/active_support/core_ext/uri.rb +3 -27
  89. data/lib/active_support/core_ext.rb +1 -0
  90. data/lib/active_support/current_attributes.rb +31 -15
  91. data/lib/active_support/dependencies/interlock.rb +10 -18
  92. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  93. data/lib/active_support/dependencies.rb +58 -788
  94. data/lib/active_support/deprecation/behaviors.rb +8 -5
  95. data/lib/active_support/deprecation/disallowed.rb +3 -3
  96. data/lib/active_support/deprecation/method_wrappers.rb +3 -3
  97. data/lib/active_support/deprecation/proxy_wrappers.rb +2 -2
  98. data/lib/active_support/deprecation.rb +2 -2
  99. data/lib/active_support/descendants_tracker.rb +174 -68
  100. data/lib/active_support/digest.rb +4 -4
  101. data/lib/active_support/duration/iso8601_parser.rb +3 -3
  102. data/lib/active_support/duration/iso8601_serializer.rb +9 -1
  103. data/lib/active_support/duration.rb +77 -48
  104. data/lib/active_support/encrypted_configuration.rb +45 -3
  105. data/lib/active_support/encrypted_file.rb +13 -1
  106. data/lib/active_support/environment_inquirer.rb +1 -1
  107. data/lib/active_support/error_reporter.rb +117 -0
  108. data/lib/active_support/evented_file_update_checker.rb +17 -6
  109. data/lib/active_support/execution_context/test_helper.rb +13 -0
  110. data/lib/active_support/execution_context.rb +53 -0
  111. data/lib/active_support/execution_wrapper.rb +30 -11
  112. data/lib/active_support/executor/test_helper.rb +7 -0
  113. data/lib/active_support/fork_tracker.rb +19 -12
  114. data/lib/active_support/gem_version.rb +5 -5
  115. data/lib/active_support/hash_with_indifferent_access.rb +3 -1
  116. data/lib/active_support/html_safe_translation.rb +43 -0
  117. data/lib/active_support/i18n.rb +1 -0
  118. data/lib/active_support/i18n_railtie.rb +1 -1
  119. data/lib/active_support/inflector/inflections.rb +23 -7
  120. data/lib/active_support/inflector/methods.rb +28 -53
  121. data/lib/active_support/inflector/transliterate.rb +1 -1
  122. data/lib/active_support/isolated_execution_state.rb +72 -0
  123. data/lib/active_support/json/encoding.rb +3 -3
  124. data/lib/active_support/key_generator.rb +22 -5
  125. data/lib/active_support/lazy_load_hooks.rb +28 -4
  126. data/lib/active_support/locale/en.yml +1 -1
  127. data/lib/active_support/log_subscriber/test_helper.rb +2 -2
  128. data/lib/active_support/log_subscriber.rb +15 -5
  129. data/lib/active_support/logger_thread_safe_level.rb +4 -13
  130. data/lib/active_support/message_encryptor.rb +12 -6
  131. data/lib/active_support/message_verifier.rb +46 -14
  132. data/lib/active_support/messages/metadata.rb +2 -2
  133. data/lib/active_support/multibyte/chars.rb +10 -11
  134. data/lib/active_support/multibyte/unicode.rb +0 -12
  135. data/lib/active_support/multibyte.rb +1 -1
  136. data/lib/active_support/notifications/fanout.rb +91 -65
  137. data/lib/active_support/notifications/instrumenter.rb +32 -15
  138. data/lib/active_support/notifications.rb +23 -23
  139. data/lib/active_support/number_helper/number_converter.rb +1 -3
  140. data/lib/active_support/number_helper/number_to_currency_converter.rb +11 -6
  141. data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -1
  142. data/lib/active_support/number_helper/number_to_human_size_converter.rb +1 -1
  143. data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -1
  144. data/lib/active_support/number_helper/rounding_helper.rb +1 -5
  145. data/lib/active_support/number_helper.rb +4 -5
  146. data/lib/active_support/option_merger.rb +10 -18
  147. data/lib/active_support/ordered_hash.rb +1 -1
  148. data/lib/active_support/ordered_options.rb +1 -1
  149. data/lib/active_support/parameter_filter.rb +20 -11
  150. data/lib/active_support/per_thread_registry.rb +5 -1
  151. data/lib/active_support/railtie.rb +69 -19
  152. data/lib/active_support/rescuable.rb +12 -12
  153. data/lib/active_support/ruby_features.rb +7 -0
  154. data/lib/active_support/secure_compare_rotator.rb +2 -2
  155. data/lib/active_support/string_inquirer.rb +0 -2
  156. data/lib/active_support/subscriber.rb +7 -18
  157. data/lib/active_support/tagged_logging.rb +1 -1
  158. data/lib/active_support/test_case.rb +13 -21
  159. data/lib/active_support/testing/assertions.rb +35 -5
  160. data/lib/active_support/testing/deprecation.rb +52 -1
  161. data/lib/active_support/testing/isolation.rb +30 -29
  162. data/lib/active_support/testing/method_call_assertions.rb +5 -5
  163. data/lib/active_support/testing/parallelization/server.rb +4 -0
  164. data/lib/active_support/testing/parallelization/worker.rb +3 -0
  165. data/lib/active_support/testing/parallelization.rb +4 -0
  166. data/lib/active_support/testing/parallelize_executor.rb +76 -0
  167. data/lib/active_support/testing/stream.rb +3 -5
  168. data/lib/active_support/testing/tagged_logging.rb +1 -1
  169. data/lib/active_support/testing/time_helpers.rb +13 -2
  170. data/lib/active_support/time_with_zone.rb +62 -22
  171. data/lib/active_support/values/time_zone.rb +33 -14
  172. data/lib/active_support/version.rb +1 -1
  173. data/lib/active_support/xml_mini/jdom.rb +1 -1
  174. data/lib/active_support/xml_mini/libxml.rb +5 -5
  175. data/lib/active_support/xml_mini/libxmlsax.rb +1 -1
  176. data/lib/active_support/xml_mini/nokogiri.rb +4 -4
  177. data/lib/active_support/xml_mini/nokogirisax.rb +1 -1
  178. data/lib/active_support/xml_mini/rexml.rb +1 -1
  179. data/lib/active_support/xml_mini.rb +5 -4
  180. data/lib/active_support.rb +16 -0
  181. metadata +28 -26
  182. data/lib/active_support/core_ext/marshal.rb +0 -26
  183. data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -120
@@ -3,32 +3,32 @@
3
3
  require "delegate"
4
4
 
5
5
  module ActiveSupport
6
- module Tryable #:nodoc:
7
- def try(method_name = nil, *args, &b)
8
- if method_name.nil? && block_given?
9
- if b.arity == 0
10
- instance_eval(&b)
6
+ module Tryable # :nodoc:
7
+ def try(*args, &block)
8
+ if args.empty? && block_given?
9
+ if block.arity == 0
10
+ instance_eval(&block)
11
11
  else
12
12
  yield self
13
13
  end
14
- elsif respond_to?(method_name)
15
- public_send(method_name, *args, &b)
14
+ elsif respond_to?(args.first)
15
+ public_send(*args, &block)
16
16
  end
17
17
  end
18
- ruby2_keywords(:try) if respond_to?(:ruby2_keywords, true)
18
+ ruby2_keywords(:try)
19
19
 
20
- def try!(method_name = nil, *args, &b)
21
- if method_name.nil? && block_given?
22
- if b.arity == 0
23
- instance_eval(&b)
20
+ def try!(*args, &block)
21
+ if args.empty? && block_given?
22
+ if block.arity == 0
23
+ instance_eval(&block)
24
24
  else
25
25
  yield self
26
26
  end
27
27
  else
28
- public_send(method_name, *args, &b)
28
+ public_send(*args, &block)
29
29
  end
30
30
  end
31
- ruby2_keywords(:try!) if respond_to?(:ruby2_keywords, true)
31
+ ruby2_keywords(:try!)
32
32
  end
33
33
  end
34
34
 
@@ -39,7 +39,7 @@ class Object
39
39
  # :method: try
40
40
  #
41
41
  # :call-seq:
42
- # try(*a, &b)
42
+ # try(*args, &block)
43
43
  #
44
44
  # Invokes the public method whose name goes as first argument just like
45
45
  # +public_send+ does, except that if the receiver does not respond to it the
@@ -104,7 +104,7 @@ class Object
104
104
  # :method: try!
105
105
  #
106
106
  # :call-seq:
107
- # try!(*a, &b)
107
+ # try!(*args, &block)
108
108
  #
109
109
  # Same as #try, but raises a +NoMethodError+ exception if the receiver is
110
110
  # not +nil+ and does not implement the tried method.
@@ -121,7 +121,7 @@ class Delegator
121
121
  # :method: try
122
122
  #
123
123
  # :call-seq:
124
- # try(a*, &b)
124
+ # try(*args, &block)
125
125
  #
126
126
  # See Object#try
127
127
 
@@ -129,7 +129,7 @@ class Delegator
129
129
  # :method: try!
130
130
  #
131
131
  # :call-seq:
132
- # try!(a*, &b)
132
+ # try!(*args, &block)
133
133
  #
134
134
  # See Object#try!
135
135
  end
@@ -145,14 +145,14 @@ class NilClass
145
145
  #
146
146
  # With +try+
147
147
  # @person.try(:children).try(:first).try(:name)
148
- def try(_method_name = nil, *)
148
+ def try(*)
149
149
  nil
150
150
  end
151
151
 
152
152
  # Calling +try!+ on +nil+ always returns +nil+.
153
153
  #
154
154
  # nil.try!(:name) # => nil
155
- def try!(_method_name = nil, *)
155
+ def try!(*)
156
156
  nil
157
157
  end
158
158
  end
@@ -64,7 +64,7 @@ class Object
64
64
  #
65
65
  # Hence the inherited default for +if+ key is ignored.
66
66
  #
67
- # NOTE: You cannot call class methods implicitly inside of with_options.
67
+ # NOTE: You cannot call class methods implicitly inside of +with_options+.
68
68
  # You can access these methods using the class name instead:
69
69
  #
70
70
  # class Phone < ActiveRecord::Base
@@ -75,8 +75,27 @@ class Object
75
75
  # end
76
76
  # end
77
77
  #
78
+ # When the block argument is omitted, the decorated Object instance is returned:
79
+ #
80
+ # module MyStyledHelpers
81
+ # def styled
82
+ # with_options style: "color: red;"
83
+ # end
84
+ # end
85
+ #
86
+ # styled.link_to "I'm red", "/"
87
+ # # => <a href="/" style="color: red;">I'm red</a>
88
+ #
89
+ # styled.button_tag "I'm red too!"
90
+ # # => <button style="color: red;">I'm red too!</button>
91
+ #
78
92
  def with_options(options, &block)
79
93
  option_merger = ActiveSupport::OptionMerger.new(self, options)
80
- block.arity.zero? ? option_merger.instance_eval(&block) : block.call(option_merger)
94
+
95
+ if block
96
+ block.arity.zero? ? option_merger.instance_eval(&block) : block.call(option_merger)
97
+ else
98
+ option_merger
99
+ end
81
100
  end
82
101
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pathname
4
+ # Returns the receiver if the named file exists otherwise returns +nil+.
5
+ # <tt>pathname.existence</tt> is equivalent to
6
+ #
7
+ # pathname.exist? ? pathname : nil
8
+ #
9
+ # For example, something like
10
+ #
11
+ # content = pathname.read if pathname.exist?
12
+ #
13
+ # becomes
14
+ #
15
+ # content = pathname.existence&.read
16
+ #
17
+ # @return [Pathname]
18
+ def existence
19
+ self if exist?
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/pathname/existence"
@@ -51,31 +51,6 @@ module ActiveSupport
51
51
  super
52
52
  end
53
53
  end
54
-
55
- # Extends the default Range#cover? to support range comparisons.
56
- # (1..5).cover?(1..5) # => true
57
- # (1..5).cover?(2..3) # => true
58
- # (1..5).cover?(1...6) # => true
59
- # (1..5).cover?(2..6) # => false
60
- #
61
- # The native Range#cover? behavior is untouched.
62
- # ('a'..'f').cover?('c') # => true
63
- # (5..9).cover?(11) # => false
64
- #
65
- # The given range must be fully bounded, with both start and end.
66
- def cover?(value)
67
- if value.is_a?(::Range)
68
- is_backwards_op = value.exclude_end? ? :>= : :>
69
- return false if value.begin && value.end && value.begin.public_send(is_backwards_op, value.end)
70
- # 1...10 covers 1..9 but it does not cover 1..10.
71
- # 1..10 covers 1...11 but it does not cover 1...12.
72
- operator = exclude_end? && !value.exclude_end? ? :< : :<=
73
- value_max = !exclude_end? && value.exclude_end? ? value.max : value.last
74
- super(value.first) && (self.end.nil? || value_max.public_send(operator, last))
75
- else
76
- super
77
- end
78
- end
79
54
  end
80
55
  end
81
56
 
@@ -7,34 +7,34 @@ module ActiveSupport
7
7
  case start
8
8
  when String then "BETWEEN '#{start}' AND '#{stop}'"
9
9
  else
10
- "BETWEEN '#{start.to_s(:db)}' AND '#{stop.to_s(:db)}'"
10
+ "BETWEEN '#{start.to_fs(:db)}' AND '#{stop.to_fs(:db)}'"
11
11
  end
12
12
  end
13
13
  }
14
14
 
15
15
  # Convert range to a formatted string. See RANGE_FORMATS for predefined formats.
16
16
  #
17
+ # This method is aliased to <tt>to_formatted_s</tt>.
18
+ #
17
19
  # range = (1..100) # => 1..100
18
20
  #
19
21
  # range.to_s # => "1..100"
20
- # range.to_s(:db) # => "BETWEEN '1' AND '100'"
22
+ # range.to_fs(:db) # => "BETWEEN '1' AND '100'"
21
23
  #
22
24
  # == Adding your own range formats to to_s
23
25
  # You can add your own formats to the Range::RANGE_FORMATS hash.
24
26
  # Use the format name as the hash key and a Proc instance.
25
27
  #
26
28
  # # config/initializers/range_formats.rb
27
- # Range::RANGE_FORMATS[:short] = ->(start, stop) { "Between #{start.to_s(:db)} and #{stop.to_s(:db)}" }
28
- def to_s(format = :default)
29
+ # Range::RANGE_FORMATS[:short] = ->(start, stop) { "Between #{start.to_fs(:db)} and #{stop.to_fs(:db)}" }
30
+ def to_fs(format = :default)
29
31
  if formatter = RANGE_FORMATS[format]
30
32
  formatter.call(first, last)
31
33
  else
32
- super()
34
+ to_s
33
35
  end
34
36
  end
35
-
36
- alias_method :to_default_s, :to_s
37
- alias_method :to_formatted_s, :to_s
37
+ alias_method :to_formatted_s, :to_fs
38
38
  end
39
39
  end
40
40
 
@@ -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)
@@ -3,7 +3,7 @@
3
3
  require "active_support/time_with_zone"
4
4
 
5
5
  module ActiveSupport
6
- module EachTimeWithZone #:nodoc:
6
+ module EachTimeWithZone # :nodoc:
7
7
  def each(&block)
8
8
  ensure_iteration_allowed
9
9
  super
@@ -1,28 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/time_with_zone"
4
- require "active_support/deprecation"
5
-
6
- module ActiveSupport
7
- module IncludeTimeWithZone #:nodoc:
8
- # Extends the default Range#include? to support ActiveSupport::TimeWithZone.
9
- #
10
- # (1.hour.ago..1.hour.from_now).include?(Time.current) # => true
11
- #
12
- def include?(value)
13
- if self.begin.is_a?(TimeWithZone) || self.end.is_a?(TimeWithZone)
14
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
15
- Using `Range#include?` to check the inclusion of a value in
16
- a date time range is deprecated.
17
- It is recommended to use `Range#cover?` instead of `Range#include?` to
18
- check the inclusion of a value in a date time range.
19
- MSG
20
- cover?(value)
21
- else
22
- super
23
- end
24
- end
25
- end
26
- end
27
-
28
- Range.prepend(ActiveSupport::IncludeTimeWithZone)
3
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
4
+ `active_support/core_ext/range/include_time_with_zone` is deprecated and will be removed in Rails 7.1.
5
+ MSG
@@ -5,6 +5,6 @@ class Range
5
5
  # (1..5).overlaps?(4..6) # => true
6
6
  # (1..5).overlaps?(7..9) # => false
7
7
  def overlaps?(other)
8
- cover?(other.first) || other.cover?(first)
8
+ other.begin == self.begin || cover?(other.begin) || other.cover?(self.begin)
9
9
  end
10
10
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_support/core_ext/range/conversions"
4
+ require "active_support/core_ext/range/deprecated_conversions" unless ENV["RAILS_DISABLE_DEPRECATED_TO_S_CONVERSION"]
4
5
  require "active_support/core_ext/range/compare_range"
5
- require "active_support/core_ext/range/include_time_with_zone"
6
6
  require "active_support/core_ext/range/overlaps"
7
7
  require "active_support/core_ext/range/each"
@@ -12,7 +12,7 @@ module SecureRandom
12
12
  #
13
13
  # If _n_ is not specified or is +nil+, 16 is assumed. It may be larger in the future.
14
14
  #
15
- # 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.
16
16
  #
17
17
  # p SecureRandom.base58 # => "4kUgL2pdQMSCQtjE"
18
18
  # p SecureRandom.base58(24) # => "77TMHrHJFvFDwodq8w7Ev2m7"
@@ -5,10 +5,10 @@ require "active_support/core_ext/time/calculations"
5
5
 
6
6
  class String
7
7
  # Converts a string to a Time value.
8
- # The +form+ can be either :utc or :local (default :local).
8
+ # The +form+ can be either +:utc+ or +:local+ (default +:local+).
9
9
  #
10
10
  # The time is parsed using Time.parse method.
11
- # 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.
12
12
  # If the date part is missing then the current date is used and if
13
13
  # the time part is missing then it is assumed to be 00:00:00.
14
14
  #
@@ -106,7 +106,7 @@ class String
106
106
  self.class.new.tap do |cut|
107
107
  cut_at = truncate_at - omission.bytesize
108
108
 
109
- scan(/\X/) do |grapheme|
109
+ each_grapheme_cluster do |grapheme|
110
110
  if cut.bytesize + grapheme.bytesize <= cut_at
111
111
  cut << grapheme
112
112
  else
@@ -97,8 +97,6 @@ class String
97
97
  # 'active_record/errors'.camelize # => "ActiveRecord::Errors"
98
98
  # 'active_record/errors'.camelize(:lower) # => "activeRecord::Errors"
99
99
  #
100
- # +camelize+ is also aliased as +camelcase+.
101
- #
102
100
  # See ActiveSupport::Inflector.camelize.
103
101
  def camelize(first_letter = :upper)
104
102
  case first_letter
@@ -124,8 +122,6 @@ class String
124
122
  # 'x-men: the last stand'.titleize # => "X Men: The Last Stand"
125
123
  # 'string_ending_with_id'.titleize(keep_id_suffix: true) # => "String Ending With Id"
126
124
  #
127
- # +titleize+ is also aliased as +titlecase+.
128
- #
129
125
  # See ActiveSupport::Inflector.titleize.
130
126
  def titleize(keep_id_suffix: false)
131
127
  ActiveSupport::Inflector.titleize(self, keep_id_suffix: keep_id_suffix)
@@ -260,7 +256,7 @@ class String
260
256
  # 'author_id'.humanize # => "Author"
261
257
  # 'author_id'.humanize(capitalize: false) # => "author"
262
258
  # '_id'.humanize # => "Id"
263
- # 'author_id'.humanize(keep_id_suffix: true) # => "Author Id"
259
+ # 'author_id'.humanize(keep_id_suffix: true) # => "Author id"
264
260
  #
265
261
  # See ActiveSupport::Inflector.humanize.
266
262
  def humanize(capitalize: true, keep_id_suffix: false)
@@ -4,7 +4,7 @@ require "active_support/string_inquirer"
4
4
  require "active_support/environment_inquirer"
5
5
 
6
6
  class String
7
- # Wraps the current string in the <tt>ActiveSupport::StringInquirer</tt> class,
7
+ # Wraps the current string in the ActiveSupport::StringInquirer class,
8
8
  # which gives you a prettier way to test for equality.
9
9
  #
10
10
  # env = 'production'.inquiry
@@ -105,7 +105,7 @@ class ERB
105
105
  # WARNING: this helper only works with valid JSON. Using this on non-JSON values
106
106
  # will open up serious XSS vulnerabilities. For example, if you replace the
107
107
  # +current_user.to_json+ in the example above with user input instead, the browser
108
- # will happily eval() that string as JavaScript.
108
+ # will happily <tt>eval()</tt> that string as JavaScript.
109
109
  #
110
110
  # The escaping performed in this method is identical to those performed in the
111
111
  # Active Support JSON encoder when +ActiveSupport.escape_html_entities_in_json+ is
@@ -158,7 +158,7 @@ class Numeric
158
158
  end
159
159
  end
160
160
 
161
- module ActiveSupport #:nodoc:
161
+ module ActiveSupport # :nodoc:
162
162
  class SafeBuffer < String
163
163
  UNSAFE_STRING_METHODS = %w(
164
164
  capitalize chomp chop delete delete_prefix delete_suffix
@@ -171,7 +171,7 @@ module ActiveSupport #:nodoc:
171
171
  alias_method :original_concat, :concat
172
172
  private :original_concat
173
173
 
174
- # Raised when <tt>ActiveSupport::SafeBuffer#safe_concat</tt> is called on unsafe buffers.
174
+ # Raised when ActiveSupport::SafeBuffer#safe_concat is called on unsafe buffers.
175
175
  class SafeConcatError < StandardError
176
176
  def initialize
177
177
  super "Could not concatenate to the buffer because it is not html safe."
@@ -212,27 +212,34 @@ module ActiveSupport #:nodoc:
212
212
  end
213
213
 
214
214
  def concat(value)
215
- super(html_escape_interpolated_argument(value))
215
+ unless value.nil?
216
+ super(implicit_html_escape_interpolated_argument(value))
217
+ end
218
+ self
216
219
  end
217
220
  alias << concat
218
221
 
222
+ def bytesplice(*args, value)
223
+ super(*args, implicit_html_escape_interpolated_argument(value))
224
+ end
225
+
219
226
  def insert(index, value)
220
- super(index, html_escape_interpolated_argument(value))
227
+ super(index, implicit_html_escape_interpolated_argument(value))
221
228
  end
222
229
 
223
230
  def prepend(value)
224
- super(html_escape_interpolated_argument(value))
231
+ super(implicit_html_escape_interpolated_argument(value))
225
232
  end
226
233
 
227
234
  def replace(value)
228
- super(html_escape_interpolated_argument(value))
235
+ super(implicit_html_escape_interpolated_argument(value))
229
236
  end
230
237
 
231
238
  def []=(*args)
232
239
  if args.length == 3
233
- super(args[0], args[1], html_escape_interpolated_argument(args[2]))
240
+ super(args[0], args[1], implicit_html_escape_interpolated_argument(args[2]))
234
241
  else
235
- super(args[0], html_escape_interpolated_argument(args[1]))
242
+ super(args[0], implicit_html_escape_interpolated_argument(args[1]))
236
243
  end
237
244
  end
238
245
 
@@ -250,9 +257,9 @@ module ActiveSupport #:nodoc:
250
257
  def %(args)
251
258
  case args
252
259
  when Hash
253
- escaped_args = args.transform_values { |arg| html_escape_interpolated_argument(arg) }
260
+ escaped_args = args.transform_values { |arg| explicit_html_escape_interpolated_argument(arg) }
254
261
  else
255
- escaped_args = Array(args).map { |arg| html_escape_interpolated_argument(arg) }
262
+ escaped_args = Array(args).map { |arg| explicit_html_escape_interpolated_argument(arg) }
256
263
  end
257
264
 
258
265
  self.class.new(super(escaped_args))
@@ -290,39 +297,60 @@ module ActiveSupport #:nodoc:
290
297
  end
291
298
 
292
299
  UNSAFE_STRING_METHODS_WITH_BACKREF.each do |unsafe_method|
293
- if unsafe_method.respond_to?(unsafe_method)
294
- class_eval <<-EOT, __FILE__, __LINE__ + 1
295
- def #{unsafe_method}(*args, &block) # def gsub(*args, &block)
296
- if block # if block
297
- to_str.#{unsafe_method}(*args) { |*params| # to_str.gsub(*args) { |*params|
298
- set_block_back_references(block, $~) # set_block_back_references(block, $~)
299
- block.call(*params) # block.call(*params)
300
- } # }
301
- else # else
302
- to_str.#{unsafe_method}(*args) # to_str.gsub(*args)
303
- end # end
304
- end # end
305
-
306
- def #{unsafe_method}!(*args, &block) # def gsub!(*args, &block)
307
- @html_safe = false # @html_safe = false
308
- if block # if block
309
- super(*args) { |*params| # super(*args) { |*params|
310
- set_block_back_references(block, $~) # set_block_back_references(block, $~)
311
- block.call(*params) # block.call(*params)
312
- } # }
313
- else # else
314
- super # super
315
- end # end
316
- end # end
317
- EOT
318
- end
300
+ class_eval <<-EOT, __FILE__, __LINE__ + 1
301
+ def #{unsafe_method}(*args, &block) # def gsub(*args, &block)
302
+ if block # if block
303
+ to_str.#{unsafe_method}(*args) { |*params| # to_str.gsub(*args) { |*params|
304
+ set_block_back_references(block, $~) # set_block_back_references(block, $~)
305
+ block.call(*params) # block.call(*params)
306
+ } # }
307
+ else # else
308
+ to_str.#{unsafe_method}(*args) # to_str.gsub(*args)
309
+ end # end
310
+ end # end
311
+
312
+ def #{unsafe_method}!(*args, &block) # def gsub!(*args, &block)
313
+ @html_safe = false # @html_safe = false
314
+ if block # if block
315
+ super(*args) { |*params| # super(*args) { |*params|
316
+ set_block_back_references(block, $~) # set_block_back_references(block, $~)
317
+ block.call(*params) # block.call(*params)
318
+ } # }
319
+ else # else
320
+ super # super
321
+ end # end
322
+ end # end
323
+ EOT
319
324
  end
320
325
 
321
326
  private
322
- def html_escape_interpolated_argument(arg)
327
+ def explicit_html_escape_interpolated_argument(arg)
323
328
  (!html_safe? || arg.html_safe?) ? arg : CGI.escapeHTML(arg.to_s)
324
329
  end
325
330
 
331
+ def implicit_html_escape_interpolated_argument(arg)
332
+ if !html_safe? || arg.html_safe?
333
+ arg
334
+ else
335
+ arg_string = begin
336
+ arg.to_str
337
+ rescue NoMethodError => error
338
+ if error.name == :to_str
339
+ str = arg.to_s
340
+ ActiveSupport::Deprecation.warn <<~MSG.squish
341
+ Implicit conversion of #{arg.class} into String by ActiveSupport::SafeBuffer
342
+ is deprecated and will be removed in Rails 7.1.
343
+ You must explicitly cast it to a String.
344
+ MSG
345
+ str
346
+ else
347
+ raise
348
+ end
349
+ end
350
+ CGI.escapeHTML(arg_string)
351
+ end
352
+ end
353
+
326
354
  def set_block_back_references(block, match_data)
327
355
  block.binding.eval("proc { |m| $~ = m }").call(match_data)
328
356
  rescue ArgumentError
@@ -1,14 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Symbol
4
- def start_with?(*prefixes)
5
- to_s.start_with?(*prefixes)
6
- end unless method_defined?(:start_with?)
7
-
8
- def end_with?(*suffixes)
9
- to_s.end_with?(*suffixes)
10
- end unless method_defined?(:end_with?)
11
-
12
4
  alias :starts_with? :start_with?
13
5
  alias :ends_with? :end_with?
14
6
  end
@@ -42,8 +42,8 @@ class Time
42
42
 
43
43
  # Layers additional behavior on Time.at so that ActiveSupport::TimeWithZone and DateTime
44
44
  # instances can be used when called with a single argument
45
- def at_with_coercion(*args)
46
- return at_without_coercion(*args) if args.size != 1
45
+ def at_with_coercion(*args, **kwargs)
46
+ return at_without_coercion(*args, **kwargs) if args.size != 1 || !kwargs.empty?
47
47
 
48
48
  # Time.at can be called with a time or numerical value
49
49
  time_or_number = args.first
@@ -56,7 +56,6 @@ class Time
56
56
  at_without_coercion(time_or_number)
57
57
  end
58
58
  end
59
- ruby2_keywords(:at_with_coercion) if respond_to?(:ruby2_keywords, true)
60
59
  alias_method :at_without_coercion, :at
61
60
  alias_method :at, :at_with_coercion
62
61
 
@@ -127,8 +126,8 @@ class Time
127
126
  # Returns a new Time where one or more of the elements have been changed according
128
127
  # to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
129
128
  # <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
130
- # the hour is passed, then minute, sec, usec and nsec is set to 0. If the hour
131
- # and minute is passed, then sec, usec and nsec is set to 0. The +options+ parameter
129
+ # the hour is passed, then minute, sec, usec, and nsec is set to 0. If the hour
130
+ # and minute is passed, then sec, usec, and nsec is set to 0. The +options+ parameter
132
131
  # takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>,
133
132
  # <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>,
134
133
  # <tt>:offset</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
@@ -180,6 +179,10 @@ class Time
180
179
  # Time.new(2015, 8, 1, 14, 35, 0).advance(hours: 1) # => 2015-08-01 15:35:00 -0700
181
180
  # Time.new(2015, 8, 1, 14, 35, 0).advance(days: 1) # => 2015-08-02 14:35:00 -0700
182
181
  # Time.new(2015, 8, 1, 14, 35, 0).advance(weeks: 1) # => 2015-08-08 14:35:00 -0700
182
+ #
183
+ # Just like Date#advance, increments are applied in order of time units from
184
+ # largest to smallest. This order can affect the result around the end of a
185
+ # month.
183
186
  def advance(options)
184
187
  unless options[:weeks].nil?
185
188
  options[:weeks], partial_weeks = options[:weeks].divmod(1)
@@ -278,7 +281,7 @@ class Time
278
281
  end
279
282
  alias :at_end_of_minute :end_of_minute
280
283
 
281
- def plus_with_duration(other) #:nodoc:
284
+ def plus_with_duration(other) # :nodoc:
282
285
  if ActiveSupport::Duration === other
283
286
  other.since(self)
284
287
  else
@@ -288,7 +291,7 @@ class Time
288
291
  alias_method :plus_without_duration, :+
289
292
  alias_method :+, :plus_with_duration
290
293
 
291
- def minus_with_duration(other) #:nodoc:
294
+ def minus_with_duration(other) # :nodoc:
292
295
  if ActiveSupport::Duration === other
293
296
  other.until(self)
294
297
  else
@@ -306,7 +309,7 @@ class Time
306
309
  other.is_a?(DateTime) ? to_f - other.to_f : minus_without_coercion(other)
307
310
  end
308
311
  alias_method :minus_without_coercion, :-
309
- alias_method :-, :minus_with_coercion
312
+ alias_method :-, :minus_with_coercion # rubocop:disable Lint/DuplicateMethods
310
313
 
311
314
  # Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
312
315
  # can be chronologically compared with a Time