activesupport 7.2.3.1 → 8.1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +584 -234
  3. data/lib/active_support/backtrace_cleaner.rb +72 -1
  4. data/lib/active_support/benchmark.rb +21 -0
  5. data/lib/active_support/benchmarkable.rb +3 -2
  6. data/lib/active_support/cache/file_store.rb +13 -2
  7. data/lib/active_support/cache/mem_cache_store.rb +17 -14
  8. data/lib/active_support/cache/memory_store.rb +9 -3
  9. data/lib/active_support/cache/redis_cache_store.rb +51 -34
  10. data/lib/active_support/cache/strategy/local_cache.rb +17 -8
  11. data/lib/active_support/cache/strategy/local_cache_middleware.rb +7 -7
  12. data/lib/active_support/cache.rb +86 -18
  13. data/lib/active_support/callbacks.rb +25 -11
  14. data/lib/active_support/class_attribute.rb +33 -0
  15. data/lib/active_support/code_generator.rb +9 -0
  16. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +8 -62
  17. data/lib/active_support/concurrency/share_lock.rb +0 -1
  18. data/lib/active_support/concurrency/thread_monitor.rb +55 -0
  19. data/lib/active_support/configurable.rb +34 -0
  20. data/lib/active_support/configuration_file.rb +15 -6
  21. data/lib/active_support/continuous_integration.rb +145 -0
  22. data/lib/active_support/core_ext/array/conversions.rb +3 -3
  23. data/lib/active_support/core_ext/array.rb +7 -7
  24. data/lib/active_support/core_ext/benchmark.rb +0 -16
  25. data/lib/active_support/core_ext/big_decimal.rb +1 -1
  26. data/lib/active_support/core_ext/class/attribute.rb +24 -18
  27. data/lib/active_support/core_ext/class.rb +2 -2
  28. data/lib/active_support/core_ext/date/conversions.rb +2 -0
  29. data/lib/active_support/core_ext/date.rb +5 -5
  30. data/lib/active_support/core_ext/date_and_time/compatibility.rb +0 -35
  31. data/lib/active_support/core_ext/date_time/calculations.rb +1 -0
  32. data/lib/active_support/core_ext/date_time/compatibility.rb +3 -5
  33. data/lib/active_support/core_ext/date_time.rb +5 -5
  34. data/lib/active_support/core_ext/digest.rb +1 -1
  35. data/lib/active_support/core_ext/enumerable.rb +8 -3
  36. data/lib/active_support/core_ext/erb/util.rb +3 -3
  37. data/lib/active_support/core_ext/file.rb +1 -1
  38. data/lib/active_support/core_ext/hash/deep_merge.rb +1 -0
  39. data/lib/active_support/core_ext/hash/except.rb +0 -12
  40. data/lib/active_support/core_ext/hash.rb +8 -8
  41. data/lib/active_support/core_ext/integer.rb +3 -3
  42. data/lib/active_support/core_ext/kernel.rb +3 -3
  43. data/lib/active_support/core_ext/module/attr_internal.rb +3 -4
  44. data/lib/active_support/core_ext/module.rb +11 -11
  45. data/lib/active_support/core_ext/numeric.rb +3 -3
  46. data/lib/active_support/core_ext/object/instance_variables.rb +1 -1
  47. data/lib/active_support/core_ext/object/json.rb +24 -11
  48. data/lib/active_support/core_ext/object/to_query.rb +7 -1
  49. data/lib/active_support/core_ext/object.rb +13 -13
  50. data/lib/active_support/core_ext/pathname.rb +2 -2
  51. data/lib/active_support/core_ext/range/compare_range.rb +2 -14
  52. data/lib/active_support/core_ext/range/overlap.rb +3 -3
  53. data/lib/active_support/core_ext/range/sole.rb +2 -0
  54. data/lib/active_support/core_ext/range.rb +4 -5
  55. data/lib/active_support/core_ext/string/filters.rb +2 -0
  56. data/lib/active_support/core_ext/string/inflections.rb +1 -1
  57. data/lib/active_support/core_ext/string/multibyte.rb +10 -1
  58. data/lib/active_support/core_ext/string/output_safety.rb +27 -13
  59. data/lib/active_support/core_ext/string.rb +13 -13
  60. data/lib/active_support/core_ext/symbol.rb +1 -1
  61. data/lib/active_support/core_ext/thread/backtrace/location.rb +2 -7
  62. data/lib/active_support/core_ext/time/calculations.rb +11 -2
  63. data/lib/active_support/core_ext/time/compatibility.rb +2 -27
  64. data/lib/active_support/core_ext/time/conversions.rb +2 -0
  65. data/lib/active_support/core_ext/time.rb +5 -5
  66. data/lib/active_support/current_attributes/test_helper.rb +2 -2
  67. data/lib/active_support/current_attributes.rb +13 -10
  68. data/lib/active_support/delegation.rb +25 -44
  69. data/lib/active_support/dependencies/interlock.rb +11 -5
  70. data/lib/active_support/dependencies.rb +6 -2
  71. data/lib/active_support/deprecation/reporting.rb +4 -21
  72. data/lib/active_support/deprecation.rb +1 -1
  73. data/lib/active_support/duration.rb +20 -16
  74. data/lib/active_support/editor.rb +70 -0
  75. data/lib/active_support/encrypted_configuration.rb +20 -2
  76. data/lib/active_support/error_reporter.rb +76 -2
  77. data/lib/active_support/event_reporter/test_helper.rb +32 -0
  78. data/lib/active_support/event_reporter.rb +592 -0
  79. data/lib/active_support/evented_file_update_checker.rb +5 -2
  80. data/lib/active_support/execution_context.rb +75 -7
  81. data/lib/active_support/file_update_checker.rb +7 -5
  82. data/lib/active_support/gem_version.rb +3 -3
  83. data/lib/active_support/gzip.rb +1 -0
  84. data/lib/active_support/hash_with_indifferent_access.rb +44 -24
  85. data/lib/active_support/i18n_railtie.rb +19 -11
  86. data/lib/active_support/inflector/inflections.rb +34 -16
  87. data/lib/active_support/inflector/methods.rb +6 -22
  88. data/lib/active_support/inflector/transliterate.rb +18 -10
  89. data/lib/active_support/isolated_execution_state.rb +17 -17
  90. data/lib/active_support/json/decoding.rb +9 -3
  91. data/lib/active_support/json/encoding.rb +149 -19
  92. data/lib/active_support/log_subscriber.rb +2 -6
  93. data/lib/active_support/logger_thread_safe_level.rb +6 -3
  94. data/lib/active_support/message_encryptors.rb +52 -0
  95. data/lib/active_support/message_pack/extensions.rb +23 -1
  96. data/lib/active_support/message_verifiers.rb +52 -0
  97. data/lib/active_support/messages/rotation_coordinator.rb +9 -0
  98. data/lib/active_support/messages/rotator.rb +5 -0
  99. data/lib/active_support/messages/serializer_with_fallback.rb +1 -1
  100. data/lib/active_support/multibyte/chars.rb +8 -1
  101. data/lib/active_support/multibyte.rb +4 -0
  102. data/lib/active_support/notifications/fanout.rb +64 -43
  103. data/lib/active_support/notifications/instrumenter.rb +1 -1
  104. data/lib/active_support/notifications.rb +2 -2
  105. data/lib/active_support/number_helper/number_converter.rb +4 -1
  106. data/lib/active_support/number_helper/number_to_currency_converter.rb +1 -1
  107. data/lib/active_support/number_helper/number_to_delimited_converter.rb +3 -4
  108. data/lib/active_support/number_helper/number_to_phone_converter.rb +3 -7
  109. data/lib/active_support/number_helper/rounding_helper.rb +1 -1
  110. data/lib/active_support/number_helper.rb +22 -0
  111. data/lib/active_support/ordered_options.rb +2 -2
  112. data/lib/active_support/railtie.rb +32 -9
  113. data/lib/active_support/security_utils.rb +4 -5
  114. data/lib/active_support/structured_event_subscriber.rb +99 -0
  115. data/lib/active_support/subscriber.rb +0 -5
  116. data/lib/active_support/syntax_error_proxy.rb +9 -1
  117. data/lib/active_support/tagged_logging.rb +5 -0
  118. data/lib/active_support/test_case.rb +67 -6
  119. data/lib/active_support/testing/assertions.rb +118 -27
  120. data/lib/active_support/testing/autorun.rb +5 -0
  121. data/lib/active_support/testing/error_reporter_assertions.rb +17 -0
  122. data/lib/active_support/testing/event_reporter_assertions.rb +227 -0
  123. data/lib/active_support/testing/isolation.rb +0 -2
  124. data/lib/active_support/testing/notification_assertions.rb +92 -0
  125. data/lib/active_support/testing/parallelization/worker.rb +7 -1
  126. data/lib/active_support/testing/parallelization.rb +17 -0
  127. data/lib/active_support/testing/tests_without_assertions.rb +1 -1
  128. data/lib/active_support/testing/time_helpers.rb +9 -4
  129. data/lib/active_support/time_with_zone.rb +36 -23
  130. data/lib/active_support/values/time_zone.rb +22 -13
  131. data/lib/active_support/xml_mini.rb +1 -2
  132. data/lib/active_support.rb +21 -9
  133. metadata +33 -17
  134. data/lib/active_support/core_ext/range/each.rb +0 -24
  135. data/lib/active_support/proxy_object.rb +0 -20
@@ -4,7 +4,7 @@
4
4
  require "json"
5
5
  require "bigdecimal"
6
6
  require "ipaddr"
7
- require "uri/generic"
7
+ require "uri"
8
8
  require "pathname"
9
9
  require "active_support/core_ext/big_decimal/conversions" # for #to_s
10
10
  require "active_support/core_ext/hash/except"
@@ -65,11 +65,9 @@ class Object
65
65
  end
66
66
  end
67
67
 
68
- if RUBY_VERSION >= "3.2"
69
- class Data # :nodoc:
70
- def as_json(options = nil)
71
- to_h.as_json(options)
72
- end
68
+ class Data # :nodoc:
69
+ def as_json(options = nil)
70
+ to_h.as_json(options)
73
71
  end
74
72
  end
75
73
 
@@ -105,7 +103,7 @@ end
105
103
 
106
104
  class Symbol
107
105
  def as_json(options = nil) # :nodoc:
108
- to_s
106
+ name
109
107
  end
110
108
  end
111
109
 
@@ -164,7 +162,12 @@ end
164
162
 
165
163
  class Array
166
164
  def as_json(options = nil) # :nodoc:
167
- map { |v| options ? v.as_json(options.dup) : v.as_json }
165
+ if options
166
+ options = options.dup.freeze unless options.frozen?
167
+ map { |v| v.as_json(options) }
168
+ else
169
+ map { |v| v.as_json }
170
+ end
168
171
  end
169
172
  end
170
173
 
@@ -184,8 +187,11 @@ class Hash
184
187
  end
185
188
 
186
189
  result = {}
187
- subset.each do |k, v|
188
- result[k.to_s] = options ? v.as_json(options.dup) : v.as_json
190
+ if options
191
+ options = options.dup.freeze unless options.frozen?
192
+ subset.each { |k, v| result[k.to_s] = v.as_json(options) }
193
+ else
194
+ subset.each { |k, v| result[k.to_s] = v.as_json }
189
195
  end
190
196
  result
191
197
  end
@@ -234,9 +240,16 @@ class Pathname # :nodoc:
234
240
  end
235
241
 
236
242
  unless IPAddr.method_defined?(:as_json, false)
243
+ # Use `IPAddr#as_json` from the IPAddr gem if the version is 1.2.7 or higher.
237
244
  class IPAddr # :nodoc:
238
245
  def as_json(options = nil)
239
- to_s
246
+ if ipv4? && prefix == 32
247
+ to_s
248
+ elsif ipv6? && prefix == 128
249
+ to_s
250
+ else
251
+ "#{self}/#{prefix}"
252
+ end
240
253
  end
241
254
  end
242
255
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "cgi"
3
+ require "cgi/escape"
4
+ require "cgi/util" if RUBY_VERSION < "3.5"
4
5
 
5
6
  class Object
6
7
  # Alias of <tt>to_s</tt>.
@@ -16,6 +17,11 @@ class Object
16
17
  end
17
18
 
18
19
  class NilClass
20
+ # Returns a CGI-escaped +key+.
21
+ def to_query(key)
22
+ CGI.escape(key.to_param)
23
+ end
24
+
19
25
  # Returns +self+.
20
26
  def to_param
21
27
  self
@@ -1,17 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/object/acts_like"
4
- require "active_support/core_ext/object/blank"
5
- require "active_support/core_ext/object/duplicable"
6
- require "active_support/core_ext/object/deep_dup"
7
- require "active_support/core_ext/object/try"
8
- require "active_support/core_ext/object/inclusion"
3
+ require_relative "object/acts_like"
4
+ require_relative "object/blank"
5
+ require_relative "object/duplicable"
6
+ require_relative "object/deep_dup"
7
+ require_relative "object/try"
8
+ require_relative "object/inclusion"
9
9
 
10
- require "active_support/core_ext/object/conversions"
11
- require "active_support/core_ext/object/instance_variables"
10
+ require_relative "object/conversions"
11
+ require_relative "object/instance_variables"
12
12
 
13
- require "active_support/core_ext/object/json"
14
- require "active_support/core_ext/object/to_param"
15
- require "active_support/core_ext/object/to_query"
16
- require "active_support/core_ext/object/with"
17
- require "active_support/core_ext/object/with_options"
13
+ require_relative "object/json"
14
+ require_relative "object/to_param"
15
+ require_relative "object/to_query"
16
+ require_relative "object/with"
17
+ require_relative "object/with_options"
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/pathname/blank"
4
- require "active_support/core_ext/pathname/existence"
3
+ require_relative "pathname/blank"
4
+ require_relative "pathname/existence"
@@ -15,13 +15,7 @@ module ActiveSupport
15
15
  # The given range must be fully bounded, with both start and end.
16
16
  def ===(value)
17
17
  if value.is_a?(::Range)
18
- is_backwards_op = value.exclude_end? ? :>= : :>
19
- return false if value.begin && value.end && value.begin.public_send(is_backwards_op, value.end)
20
- # 1...10 includes 1..9 but it does not include 1..10.
21
- # 1..10 includes 1...11 but it does not include 1...12.
22
- operator = exclude_end? && !value.exclude_end? ? :< : :<=
23
- value_max = !exclude_end? && value.exclude_end? ? value.max : value.last
24
- super(value.first) && (self.end.nil? || value_max.public_send(operator, last))
18
+ cover?(value)
25
19
  else
26
20
  super
27
21
  end
@@ -40,13 +34,7 @@ module ActiveSupport
40
34
  # The given range must be fully bounded, with both start and end.
41
35
  def include?(value)
42
36
  if value.is_a?(::Range)
43
- is_backwards_op = value.exclude_end? ? :>= : :>
44
- return false if value.begin && value.end && value.begin.public_send(is_backwards_op, value.end)
45
- # 1...10 includes 1..9 but it does not include 1..10.
46
- # 1..10 includes 1...11 but it does not include 1...12.
47
- operator = exclude_end? && !value.exclude_end? ? :< : :<=
48
- value_max = !exclude_end? && value.exclude_end? ? value.max : value.last
49
- super(value.first) && (self.end.nil? || value_max.public_send(operator, last))
37
+ cover?(value)
50
38
  else
51
39
  super
52
40
  end
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Range
4
- # Compare two ranges and see if they overlap each other
5
- # (1..5).overlap?(4..6) # => true
6
- # (1..5).overlap?(7..9) # => false
7
4
  unless Range.method_defined?(:overlap?) # Ruby 3.3+
5
+ # Compare two ranges and see if they overlap each other
6
+ # (1..5).overlap?(4..6) # => true
7
+ # (1..5).overlap?(7..9) # => false
8
8
  def overlap?(other)
9
9
  raise TypeError unless other.is_a? Range
10
10
 
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_support/core_ext/enumerable"
4
+
3
5
  class Range
4
6
  # Returns the sole item in the range. If there are no items, or more
5
7
  # than one item, raises Enumerable::SoleItemExpectedError.
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/range/conversions"
4
- require "active_support/core_ext/range/compare_range"
5
- require "active_support/core_ext/range/overlap"
6
- require "active_support/core_ext/range/each"
7
- require "active_support/core_ext/range/sole"
3
+ require_relative "range/conversions"
4
+ require_relative "range/compare_range"
5
+ require_relative "range/overlap"
6
+ require_relative "range/sole"
@@ -72,6 +72,8 @@ class String
72
72
 
73
73
  omission = options[:omission] || "..."
74
74
  length_with_room_for_omission = truncate_to - omission.length
75
+ return omission.dup if length_with_room_for_omission <= 0
76
+
75
77
  stop = \
76
78
  if options[:separator]
77
79
  rindex(options[:separator], length_with_room_for_omission) || length_with_room_for_omission
@@ -248,7 +248,7 @@ class String
248
248
  # optional parameter +capitalize+ to false.
249
249
  # By default, this parameter is true.
250
250
  #
251
- # The trailing '_id' can be kept and capitalized by setting the
251
+ # The trailing '_id' can be kept by setting the
252
252
  # optional parameter +keep_id_suffix+ to true.
253
253
  # By default, this parameter is false.
254
254
  #
@@ -35,7 +35,16 @@ class String
35
35
  # For more information about the methods defined on the Chars proxy see ActiveSupport::Multibyte::Chars. For
36
36
  # information about how to change the default Multibyte behavior see ActiveSupport::Multibyte.
37
37
  def mb_chars
38
- ActiveSupport::Multibyte.proxy_class.new(self)
38
+ ActiveSupport.deprecator.warn(
39
+ "String#mb_chars is deprecated and will be removed in Rails 8.2. " \
40
+ "Use normal string methods instead."
41
+ )
42
+
43
+ if ActiveSupport::Multibyte.proxy_class == ActiveSupport::Multibyte::Chars
44
+ ActiveSupport::Multibyte::Chars.new(self, deprecation: false)
45
+ else
46
+ ActiveSupport::Multibyte.proxy_class.new(self)
47
+ end
39
48
  end
40
49
 
41
50
  # Returns +true+ if string has utf_8 encoding.
@@ -67,14 +67,13 @@ module ActiveSupport # :nodoc:
67
67
  original_concat(value)
68
68
  end
69
69
 
70
- def initialize(str = "")
71
- @html_safe = true
70
+ def initialize(_str = "")
72
71
  super
73
72
  end
74
73
 
75
74
  def initialize_copy(other)
76
75
  super
77
- @html_safe = other.html_safe?
76
+ @html_unsafe = true unless other.html_safe?
78
77
  end
79
78
 
80
79
  def concat(value)
@@ -116,7 +115,9 @@ module ActiveSupport # :nodoc:
116
115
  def *(_)
117
116
  new_string = super
118
117
  new_safe_buffer = new_string.is_a?(SafeBuffer) ? new_string : SafeBuffer.new(new_string)
119
- new_safe_buffer.instance_variable_set(:@html_safe, @html_safe)
118
+ if @html_unsafe
119
+ new_safe_buffer.mark_unsafe!
120
+ end
120
121
  new_safe_buffer
121
122
  end
122
123
 
@@ -129,18 +130,24 @@ module ActiveSupport # :nodoc:
129
130
  end
130
131
 
131
132
  new_safe_buffer = self.class.new(super(escaped_args))
132
- new_safe_buffer.instance_variable_set(:@html_safe, @html_safe)
133
+ if @html_unsafe
134
+ new_safe_buffer.mark_unsafe!
135
+ end
133
136
  new_safe_buffer
134
137
  end
135
138
 
136
- attr_reader :html_safe
137
- alias_method :html_safe?, :html_safe
138
- remove_method :html_safe
139
+ def html_safe?
140
+ @html_unsafe.nil?
141
+ end
139
142
 
140
143
  def to_s
141
144
  self
142
145
  end
143
146
 
147
+ def as_json(*)
148
+ to_str
149
+ end
150
+
144
151
  def to_param
145
152
  to_str
146
153
  end
@@ -157,7 +164,7 @@ module ActiveSupport # :nodoc:
157
164
  end # end
158
165
 
159
166
  def #{unsafe_method}!(*args) # def capitalize!(*args)
160
- @html_safe = false # @html_safe = false
167
+ @html_unsafe = true # @html_unsafe = true
161
168
  super # super
162
169
  end # end
163
170
  EOT
@@ -178,7 +185,7 @@ module ActiveSupport # :nodoc:
178
185
  end # end
179
186
 
180
187
  def #{unsafe_method}!(*args, &block) # def gsub!(*args, &block)
181
- @html_safe = false # @html_safe = false
188
+ @html_unsafe = true # @html_unsafe = true
182
189
  if block # if block
183
190
  super(*args) { |*params| # super(*args) { |*params|
184
191
  set_block_back_references(block, $~) # set_block_back_references(block, $~)
@@ -191,16 +198,21 @@ module ActiveSupport # :nodoc:
191
198
  EOT
192
199
  end
193
200
 
201
+ protected
202
+ def mark_unsafe!
203
+ @html_unsafe = true
204
+ end
205
+
194
206
  private
195
207
  def explicit_html_escape_interpolated_argument(arg)
196
- (!html_safe? || arg.html_safe?) ? arg : CGI.escapeHTML(arg.to_s)
208
+ (!html_safe? || arg.html_safe?) ? arg : ERB::Util.unwrapped_html_escape(arg)
197
209
  end
198
210
 
199
211
  def implicit_html_escape_interpolated_argument(arg)
200
212
  if !html_safe? || arg.html_safe?
201
213
  arg
202
214
  else
203
- CGI.escapeHTML(arg.to_str)
215
+ ERB::Util.unwrapped_html_escape(arg.to_str)
204
216
  end
205
217
  end
206
218
 
@@ -212,7 +224,9 @@ module ActiveSupport # :nodoc:
212
224
 
213
225
  def string_into_safe_buffer(new_string, is_html_safe)
214
226
  new_safe_buffer = new_string.is_a?(SafeBuffer) ? new_string : SafeBuffer.new(new_string)
215
- new_safe_buffer.instance_variable_set :@html_safe, is_html_safe
227
+ unless is_html_safe
228
+ new_safe_buffer.instance_variable_set :@html_unsafe, true
229
+ end
216
230
  new_safe_buffer
217
231
  end
218
232
  end
@@ -1,15 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/string/conversions"
4
- require "active_support/core_ext/string/filters"
5
- require "active_support/core_ext/string/multibyte"
6
- require "active_support/core_ext/string/starts_ends_with"
7
- require "active_support/core_ext/string/inflections"
8
- require "active_support/core_ext/string/access"
9
- require "active_support/core_ext/string/behavior"
10
- require "active_support/core_ext/string/output_safety"
11
- require "active_support/core_ext/string/exclude"
12
- require "active_support/core_ext/string/strip"
13
- require "active_support/core_ext/string/inquiry"
14
- require "active_support/core_ext/string/indent"
15
- require "active_support/core_ext/string/zones"
3
+ require_relative "string/conversions"
4
+ require_relative "string/filters"
5
+ require_relative "string/multibyte"
6
+ require_relative "string/starts_ends_with"
7
+ require_relative "string/inflections"
8
+ require_relative "string/access"
9
+ require_relative "string/behavior"
10
+ require_relative "string/output_safety"
11
+ require_relative "string/exclude"
12
+ require_relative "string/strip"
13
+ require_relative "string/inquiry"
14
+ require_relative "string/indent"
15
+ require_relative "string/zones"
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/symbol/starts_ends_with"
3
+ require_relative "symbol/starts_ends_with"
@@ -1,12 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Thread::Backtrace::Location # :nodoc:
4
- if defined?(ErrorHighlight) && Gem::Version.new(ErrorHighlight::VERSION) >= Gem::Version.new("0.4.0")
5
- def spot(ex)
6
- ErrorHighlight.spot(ex, backtrace_location: self)
7
- end
8
- else
9
- def spot(ex)
10
- end
4
+ def spot(ex)
5
+ ErrorHighlight.spot(ex, backtrace_location: self)
11
6
  end
12
7
  end
@@ -6,6 +6,7 @@ require "active_support/time_with_zone"
6
6
  require "active_support/core_ext/time/zones"
7
7
  require "active_support/core_ext/date_and_time/calculations"
8
8
  require "active_support/core_ext/date/calculations"
9
+ require "active_support/core_ext/module/redefine_method"
9
10
  require "active_support/core_ext/module/remove_method"
10
11
 
11
12
  class Time
@@ -59,6 +60,8 @@ class Time
59
60
  alias_method :at_without_coercion, :at
60
61
  alias_method :at, :at_with_coercion
61
62
 
63
+ silence_redefinition_of_method :rfc3339
64
+
62
65
  # Creates a +Time+ instance from an RFC 3339 string.
63
66
  #
64
67
  # Time.rfc3339('1999-12-31T14:00:00-10:00') # => 2000-01-01 00:00:00 -1000
@@ -147,6 +150,13 @@ class Time
147
150
  elsif zone.respond_to?(:utc_to_local)
148
151
  new_time = ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, zone)
149
152
 
153
+ # Some versions of Ruby have a bug where Time.new with a zone object and
154
+ # fractional seconds will end up with a broken utc_offset.
155
+ # This is fixed in Ruby 3.3.1 and 3.2.4
156
+ unless new_time.utc_offset.integer?
157
+ new_time += 0
158
+ end
159
+
150
160
  # When there are two occurrences of a nominal time due to DST ending,
151
161
  # `Time.new` chooses the first chronological occurrence (the one with a
152
162
  # larger UTC offset). However, for `change`, we want to choose the
@@ -185,6 +195,7 @@ class Time
185
195
  # largest to smallest. This order can affect the result around the end of a
186
196
  # month.
187
197
  def advance(options)
198
+ options = options.dup
188
199
  unless options[:weeks].nil?
189
200
  options[:weeks], partial_weeks = options[:weeks].divmod(1)
190
201
  options[:days] = options.fetch(:days, 0) + 7 * partial_weeks
@@ -217,8 +228,6 @@ class Time
217
228
  # Returns a new Time representing the time a number of seconds since the instance time
218
229
  def since(seconds)
219
230
  self + seconds
220
- rescue
221
- to_datetime.since(seconds)
222
231
  end
223
232
  alias :in :since
224
233
 
@@ -8,33 +8,8 @@ class Time
8
8
 
9
9
  silence_redefinition_of_method :to_time
10
10
 
11
- # Either return +self+ or the time in the local system timezone depending
12
- # on the setting of +ActiveSupport.to_time_preserves_timezone+.
11
+ # Return +self+.
13
12
  def to_time
14
- preserve_timezone ? self : getlocal
13
+ self
15
14
  end
16
-
17
- def preserve_timezone # :nodoc:
18
- system_local_time? || super
19
- end
20
-
21
- private
22
- def system_local_time?
23
- if ::Time.equal?(self.class)
24
- zone = self.zone
25
- String === zone &&
26
- (zone != "UTC" || active_support_local_zone == "UTC")
27
- end
28
- end
29
-
30
- @@active_support_local_tz = nil
31
-
32
- def active_support_local_zone
33
- @@active_support_local_zone = nil if @@active_support_local_tz != ENV["TZ"]
34
- @@active_support_local_zone ||=
35
- begin
36
- @@active_support_local_tz = ENV["TZ"]
37
- Time.new.zone
38
- end
39
- end
40
15
  end
@@ -22,6 +22,7 @@ class Time
22
22
  offset_format = time.formatted_offset(false)
23
23
  time.strftime("%a, %d %b %Y %H:%M:%S #{offset_format}")
24
24
  },
25
+ rfc2822: lambda { |time| time.rfc2822 },
25
26
  iso8601: lambda { |time| time.iso8601 }
26
27
  }
27
28
 
@@ -40,6 +41,7 @@ class Time
40
41
  # time.to_fs(:long) # => "January 18, 2007 06:10"
41
42
  # time.to_fs(:long_ordinal) # => "January 18th, 2007 06:10"
42
43
  # time.to_fs(:rfc822) # => "Thu, 18 Jan 2007 06:10:17 -0600"
44
+ # time.to_fs(:rfc2822) # => "Thu, 18 Jan 2007 06:10:17 -0600"
43
45
  # time.to_fs(:iso8601) # => "2007-01-18T06:10:17-06:00"
44
46
  #
45
47
  # == Adding your own time formats to +to_fs+
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/time/acts_like"
4
- require "active_support/core_ext/time/calculations"
5
- require "active_support/core_ext/time/compatibility"
6
- require "active_support/core_ext/time/conversions"
7
- require "active_support/core_ext/time/zones"
3
+ require_relative "time/acts_like"
4
+ require_relative "time/calculations"
5
+ require_relative "time/compatibility"
6
+ require_relative "time/conversions"
7
+ require_relative "time/zones"
@@ -2,12 +2,12 @@
2
2
 
3
3
  module ActiveSupport::CurrentAttributes::TestHelper # :nodoc:
4
4
  def before_setup
5
- ActiveSupport::CurrentAttributes.reset_all
5
+ ActiveSupport::CurrentAttributes.clear_all
6
6
  super
7
7
  end
8
8
 
9
9
  def after_teardown
10
10
  super
11
- ActiveSupport::CurrentAttributes.reset_all
11
+ ActiveSupport::CurrentAttributes.clear_all
12
12
  end
13
13
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_support/callbacks"
4
+ require "active_support/execution_context"
4
5
  require "active_support/core_ext/object/with"
5
6
  require "active_support/core_ext/enumerable"
6
7
  require "active_support/core_ext/module/delegation"
@@ -125,13 +126,13 @@ module ActiveSupport
125
126
  owner.define_cached_method(name, namespace: :current_attributes) do |batch|
126
127
  batch <<
127
128
  "def #{name}" <<
128
- "attributes[:#{name}]" <<
129
+ "@attributes[:#{name}]" <<
129
130
  "end"
130
131
  end
131
132
  owner.define_cached_method("#{name}=", namespace: :current_attributes) do |batch|
132
133
  batch <<
133
134
  "def #{name}=(value)" <<
134
- "attributes[:#{name}] = value" <<
135
+ "@attributes[:#{name}] = value" <<
135
136
  "end"
136
137
  end
137
138
  end
@@ -153,13 +154,11 @@ module ActiveSupport
153
154
 
154
155
  delegate :set, :reset, to: :instance
155
156
 
156
- def reset_all # :nodoc:
157
- current_instances.each_value(&:reset)
158
- end
159
-
160
157
  def clear_all # :nodoc:
161
- reset_all
162
- current_instances.clear
158
+ if instances = current_instances
159
+ instances.values.each(&:reset)
160
+ instances.clear
161
+ end
163
162
  end
164
163
 
165
164
  private
@@ -168,7 +167,7 @@ module ActiveSupport
168
167
  end
169
168
 
170
169
  def current_instances
171
- IsolatedExecutionState[:current_attributes_instances] ||= {}
170
+ ExecutionContext.current_attributes_instances
172
171
  end
173
172
 
174
173
  def current_instances_key
@@ -201,12 +200,16 @@ module ActiveSupport
201
200
 
202
201
  class_attribute :defaults, instance_writer: false, default: {}.freeze
203
202
 
204
- attr_accessor :attributes
203
+ attr_writer :attributes
205
204
 
206
205
  def initialize
207
206
  @attributes = resolve_defaults
208
207
  end
209
208
 
209
+ def attributes
210
+ @attributes.dup
211
+ end
212
+
210
213
  # Expose one or more attributes within a block. Old values are returned after the block concludes.
211
214
  # Example demonstrating the common use of needing to set Current attributes outside the request-cycle:
212
215
  #