activesupport 8.0.4 → 8.1.0

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 (92) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +296 -172
  3. data/lib/active_support/backtrace_cleaner.rb +71 -0
  4. data/lib/active_support/cache/mem_cache_store.rb +13 -13
  5. data/lib/active_support/cache/redis_cache_store.rb +36 -30
  6. data/lib/active_support/cache/strategy/local_cache.rb +16 -7
  7. data/lib/active_support/cache/strategy/local_cache_middleware.rb +7 -7
  8. data/lib/active_support/cache.rb +69 -6
  9. data/lib/active_support/callbacks.rb +20 -8
  10. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +8 -62
  11. data/lib/active_support/concurrency/thread_monitor.rb +55 -0
  12. data/lib/active_support/configurable.rb +34 -0
  13. data/lib/active_support/continuous_integration.rb +145 -0
  14. data/lib/active_support/core_ext/array.rb +7 -7
  15. data/lib/active_support/core_ext/benchmark.rb +4 -12
  16. data/lib/active_support/core_ext/big_decimal.rb +1 -1
  17. data/lib/active_support/core_ext/class.rb +2 -2
  18. data/lib/active_support/core_ext/date.rb +5 -5
  19. data/lib/active_support/core_ext/date_and_time/compatibility.rb +0 -35
  20. data/lib/active_support/core_ext/date_time/compatibility.rb +3 -5
  21. data/lib/active_support/core_ext/date_time.rb +5 -5
  22. data/lib/active_support/core_ext/digest.rb +1 -1
  23. data/lib/active_support/core_ext/erb/util.rb +3 -3
  24. data/lib/active_support/core_ext/file.rb +1 -1
  25. data/lib/active_support/core_ext/hash.rb +8 -8
  26. data/lib/active_support/core_ext/integer.rb +3 -3
  27. data/lib/active_support/core_ext/kernel.rb +3 -3
  28. data/lib/active_support/core_ext/module.rb +11 -11
  29. data/lib/active_support/core_ext/numeric.rb +3 -3
  30. data/lib/active_support/core_ext/object/json.rb +8 -1
  31. data/lib/active_support/core_ext/object/to_query.rb +5 -0
  32. data/lib/active_support/core_ext/object.rb +13 -13
  33. data/lib/active_support/core_ext/pathname.rb +2 -2
  34. data/lib/active_support/core_ext/range.rb +4 -5
  35. data/lib/active_support/core_ext/string/multibyte.rb +10 -1
  36. data/lib/active_support/core_ext/string/output_safety.rb +19 -12
  37. data/lib/active_support/core_ext/string.rb +13 -13
  38. data/lib/active_support/core_ext/symbol.rb +1 -1
  39. data/lib/active_support/core_ext/time/calculations.rb +0 -7
  40. data/lib/active_support/core_ext/time/compatibility.rb +2 -27
  41. data/lib/active_support/core_ext/time.rb +5 -5
  42. data/lib/active_support/core_ext.rb +1 -1
  43. data/lib/active_support/current_attributes/test_helper.rb +2 -2
  44. data/lib/active_support/current_attributes.rb +13 -10
  45. data/lib/active_support/dependencies/interlock.rb +11 -5
  46. data/lib/active_support/dependencies.rb +6 -1
  47. data/lib/active_support/deprecation/reporting.rb +4 -2
  48. data/lib/active_support/deprecation.rb +1 -1
  49. data/lib/active_support/editor.rb +70 -0
  50. data/lib/active_support/error_reporter.rb +50 -6
  51. data/lib/active_support/event_reporter/test_helper.rb +32 -0
  52. data/lib/active_support/event_reporter.rb +592 -0
  53. data/lib/active_support/evented_file_update_checker.rb +5 -1
  54. data/lib/active_support/execution_context.rb +64 -7
  55. data/lib/active_support/file_update_checker.rb +7 -5
  56. data/lib/active_support/gem_version.rb +2 -2
  57. data/lib/active_support/gzip.rb +1 -0
  58. data/lib/active_support/hash_with_indifferent_access.rb +27 -7
  59. data/lib/active_support/i18n_railtie.rb +1 -2
  60. data/lib/active_support/inflector/inflections.rb +31 -15
  61. data/lib/active_support/inflector/transliterate.rb +6 -8
  62. data/lib/active_support/isolated_execution_state.rb +12 -15
  63. data/lib/active_support/json/decoding.rb +2 -2
  64. data/lib/active_support/json/encoding.rb +135 -17
  65. data/lib/active_support/log_subscriber.rb +2 -6
  66. data/lib/active_support/message_encryptors.rb +52 -0
  67. data/lib/active_support/message_pack/extensions.rb +5 -0
  68. data/lib/active_support/message_verifiers.rb +52 -0
  69. data/lib/active_support/messages/rotation_coordinator.rb +9 -0
  70. data/lib/active_support/messages/rotator.rb +5 -0
  71. data/lib/active_support/multibyte/chars.rb +8 -1
  72. data/lib/active_support/multibyte.rb +4 -0
  73. data/lib/active_support/notifications/fanout.rb +64 -42
  74. data/lib/active_support/railtie.rb +32 -15
  75. data/lib/active_support/structured_event_subscriber.rb +99 -0
  76. data/lib/active_support/subscriber.rb +0 -5
  77. data/lib/active_support/syntax_error_proxy.rb +3 -0
  78. data/lib/active_support/test_case.rb +61 -6
  79. data/lib/active_support/testing/assertions.rb +34 -6
  80. data/lib/active_support/testing/error_reporter_assertions.rb +18 -1
  81. data/lib/active_support/testing/event_reporter_assertions.rb +227 -0
  82. data/lib/active_support/testing/notification_assertions.rb +92 -0
  83. data/lib/active_support/testing/parallelization/worker.rb +2 -0
  84. data/lib/active_support/testing/parallelization.rb +13 -0
  85. data/lib/active_support/testing/tests_without_assertions.rb +1 -1
  86. data/lib/active_support/testing/time_helpers.rb +7 -3
  87. data/lib/active_support/time_with_zone.rb +22 -22
  88. data/lib/active_support/values/time_zone.rb +8 -1
  89. data/lib/active_support/xml_mini.rb +1 -2
  90. data/lib/active_support.rb +20 -15
  91. metadata +24 -17
  92. data/lib/active_support/core_ext/range/each.rb +0 -24
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 32beba8624850f5da4cad945a95adadbf26c3469dc4da4f231412b37b6fbc070
4
- data.tar.gz: 66eec5b8c43f67d79449762999acce95b9c73a93800197bdaca5f22033876819
3
+ metadata.gz: 8e2e34de82e59790b784a08b2471fa7427da0b1642763bba5904ad1aa6ad45a8
4
+ data.tar.gz: fadad2b6a958becb7cc187251643463d43127d28af9098631050c4b368079dcc
5
5
  SHA512:
6
- metadata.gz: 1eb3ea47ffa973a4c8378e804c7bf69e03013d39b30f73e5a80285672fa8aa1d109385ea3b9dff14f438d38e39ee47e6333567a385cd3bf0a64371b7e546757b
7
- data.tar.gz: f204a3f69b69120cd00b904589a0d6bdfbf0f9655c2f6fd20070af01799b1851dead84e44c9c3ef3af1f70e56cc4323de07dad8dc14128624aba904f48c9dd83
6
+ metadata.gz: 1d545e02442de9422d3b62f261fdba69bbf9aaa95e2f8138a62493dd090397a163841044b5fb538a1e1be2ab70a464e51a7eb3ee56f12f778ecb7cc681ea6dab
7
+ data.tar.gz: d6de04f518b4802721210693b496f28ac80d16f3d7aa78bedeb007c4c850d0084d532a8b696b079f41412e274e5e29ff3644b95adfbf861f6852cfc0675ac516
data/CHANGELOG.md CHANGED
@@ -1,4 +1,33 @@
1
- ## Rails 8.0.4 (October 28, 2025) ##
1
+ ## Rails 8.1.0 (October 22, 2025) ##
2
+
3
+ * Remove deprecated passing a Time object to `Time#since`.
4
+
5
+ *Rafael Mendonça França*
6
+
7
+ * Remove deprecated `Benchmark.ms` method. It is now defined in the `benchmark` gem.
8
+
9
+ *Rafael Mendonça França*
10
+
11
+ * Remove deprecated addition for `Time` instances with `ActiveSupport::TimeWithZone`.
12
+
13
+ *Rafael Mendonça França*
14
+
15
+ * Remove deprecated support for `to_time` to preserve the system local time. It will now always preserve the receiver
16
+ timezone.
17
+
18
+ *Rafael Mendonça França*
19
+
20
+ * Deprecate `config.active_support.to_time_preserves_timezone`.
21
+
22
+ *Rafael Mendonça França*
23
+
24
+ * Standardize event name formatting in `assert_event_reported` error messages.
25
+
26
+ The event name in failure messages now uses `.inspect` (e.g., `name: "user.created"`)
27
+ to match `assert_events_reported` and provide type clarity between strings and symbols.
28
+ This only affects tests that assert on the failure message format itself.
29
+
30
+ *George Ma*
2
31
 
3
32
  * Fix `Enumerable#sole` to return the full tuple instead of just the first element of the tuple.
4
33
 
@@ -11,6 +40,15 @@
11
40
 
12
41
  *Joshua Young*
13
42
 
43
+ * Add `config.active_support.escape_js_separators_in_json`.
44
+
45
+ Introduce a new framework default to skip escaping LINE SEPARATOR (U+2028) and PARAGRAPH SEPARATOR (U+2029) in JSON.
46
+
47
+ Historically these characters were not valid inside JavaScript literal strings but that changed in ECMAScript 2019.
48
+ As such it's no longer a concern in modern browsers: https://caniuse.com/mdn-javascript_builtins_json_json_superset.
49
+
50
+ *Étienne Barrié*, *Jean Boussier*
51
+
14
52
  * Fix `NameError` when `class_attribute` is defined on instance singleton classes.
15
53
 
16
54
  Previously, calling `class_attribute` on an instance's singleton class would raise
@@ -24,313 +62,399 @@
24
62
 
25
63
  *Joshua Young*
26
64
 
65
+ * Introduce `ActiveSupport::Testing::EventReporterAssertions#with_debug_event_reporting`
66
+ to enable event reporter debug mode in tests.
27
67
 
28
- ## Rails 8.0.3 (September 22, 2025) ##
68
+ The previous way to enable debug mode is by using `#with_debug` on the
69
+ event reporter itself, which is too verbose. This new helper will help
70
+ clear up any confusion on how to test debug events.
29
71
 
30
- * `ActiveSupport::FileUpdateChecker` does not depend on `Time.now` to prevent unnecessary reloads with time travel test helpers
72
+ *Gannon McGibbon*
31
73
 
32
- *Jan Grodowski*
74
+ * Add `ActiveSupport::StructuredEventSubscriber` for consuming notifications and
75
+ emitting structured event logs. Events may be emitted with the `#emit_event`
76
+ or `#emit_debug_event` methods.
33
77
 
34
- * Fix `ActiveSupport::BroadcastLogger` from executing a block argument for each logger (tagged, info, etc.).
78
+ ```ruby
79
+ class MyStructuredEventSubscriber < ActiveSupport::StructuredEventSubscriber
80
+ def notification(event)
81
+ emit_event("my.notification", data: 1)
82
+ end
83
+ end
84
+ ```
35
85
 
36
- *Jared Armstrong*
86
+ *Adrianna Chang*
37
87
 
38
- * Make `ActiveSupport::Logger` `#freeze`-friendly.
88
+ * `ActiveSupport::FileUpdateChecker` does not depend on `Time.now` to prevent unecessary reloads with time travel test helpers
39
89
 
40
- *Joshua Young*
90
+ *Jan Grodowski*
41
91
 
42
- * Fix `ActiveSupport::HashWithIndifferentAccess#transform_keys!` removing defaults.
92
+ * Add `ActiveSupport::Cache::Store#namespace=` and `#namespace`.
43
93
 
44
- *Hartley McGuire*
94
+ Can be used as an alternative to `Store#clear` in some situations such as parallel
95
+ testing.
45
96
 
46
- * Fix `ActiveSupport::HashWithIndifferentAccess#tranform_keys!` to handle collisions.
97
+ *Nick Schwaderer*
47
98
 
48
- If the transformation would result in a key equal to another not yet transformed one,
49
- it would result in keys being lost.
99
+ * Create `parallel_worker_id` helper for running parallel tests. This allows users to
100
+ know which worker they are currently running in.
50
101
 
51
- Before:
102
+ *Nick Schwaderer*
52
103
 
53
- ```ruby
54
- >> {a: 1, b: 2}.with_indifferent_access.transform_keys!(&:succ)
55
- => {"c" => 1}
56
- ```
104
+ * Make the cache of `ActiveSupport::Cache::Strategy::LocalCache::Middleware` updatable.
57
105
 
58
- After:
106
+ If the cache client at `Rails.cache` of a booted application changes, the corresponding
107
+ mounted middleware needs to update in order for request-local caches to be setup properly.
108
+ Otherwise, redundant cache operations will erroneously hit the datastore.
59
109
 
60
- ```ruby
61
- >> {a: 1, b: 2}.with_indifferent_access.transform_keys!(&:succ)
62
- => {"b" => 1, "c" => 2}
63
- ```
110
+ *Gannon McGibbon*
64
111
 
65
- *Jason T Johnson*, *Jean Boussier*
112
+ * Add `assert_events_reported` test helper for `ActiveSupport::EventReporter`.
66
113
 
67
- * Fix `ActiveSupport::Cache::MemCacheStore#read_multi` to handle network errors.
114
+ This new assertion allows testing multiple events in a single block, regardless of order:
68
115
 
69
- This method specifically wasn't handling network errors like other codepaths.
116
+ ```ruby
117
+ assert_events_reported([
118
+ { name: "user.created", payload: { id: 123 } },
119
+ { name: "email.sent", payload: { to: "user@example.com" } }
120
+ ]) do
121
+ create_user_and_send_welcome_email
122
+ end
123
+ ```
70
124
 
71
- *Alessandro Dal Grande*
125
+ *George Ma*
72
126
 
73
- * Fix configuring `RedisCacheStore` with `raw: true`.
127
+ * Add `ActiveSupport::TimeZone#standard_name` method.
74
128
 
75
- *fatkodima*
129
+ ``` ruby
130
+ zone = ActiveSupport::TimeZone['Hawaii']
131
+ # Old way
132
+ ActiveSupport::TimeZone::MAPPING[zone.name]
133
+ # New way
134
+ zone.standard_name # => 'Pacific/Honolulu'
135
+ ```
76
136
 
77
- * Fix `Enumerable#sole` for infinite collections.
137
+ *Bogdan Gusiev*
78
138
 
79
- *fatkodima*
139
+ * Add Structured Event Reporter, accessible via `Rails.event`.
80
140
 
141
+ The Event Reporter provides a unified interface for producing structured events in Rails
142
+ applications:
81
143
 
82
- ## Rails 8.0.2.1 (August 13, 2025) ##
144
+ ```ruby
145
+ Rails.event.notify("user.signup", user_id: 123, email: "user@example.com")
146
+ ```
83
147
 
84
- * No changes.
148
+ It supports adding tags to events:
85
149
 
150
+ ```ruby
151
+ Rails.event.tagged("graphql") do
152
+ # Event includes tags: { graphql: true }
153
+ Rails.event.notify("user.signup", user_id: 123, email: "user@example.com")
154
+ end
155
+ ```
86
156
 
87
- ## Rails 8.0.2 (March 12, 2025) ##
157
+ As well as context:
158
+ ```ruby
159
+ # All events will contain context: {request_id: "abc123", shop_id: 456}
160
+ Rails.event.set_context(request_id: "abc123", shop_id: 456)
161
+ ```
88
162
 
89
- * Fix setting `to_time_preserves_timezone` from `new_framework_defaults_8_0.rb`.
163
+ Events are emitted to subscribers. Applications register subscribers to
164
+ control how events are serialized and emitted. Subscribers must implement
165
+ an `#emit` method, which receives the event hash:
90
166
 
91
- *fatkodima*
167
+ ```ruby
168
+ class LogSubscriber
169
+ def emit(event)
170
+ payload = event[:payload].map { |key, value| "#{key}=#{value}" }.join(" ")
171
+ source_location = event[:source_location]
172
+ log = "[#{event[:name]}] #{payload} at #{source_location[:filepath]}:#{source_location[:lineno]}"
173
+ Rails.logger.info(log)
174
+ end
175
+ end
176
+ ```
92
177
 
93
- * Fix Active Support Cache `fetch_multi` when local store is active.
178
+ *Adrianna Chang*
94
179
 
95
- `fetch_multi` now properly yield to the provided block for missing entries
96
- that have been recorded as such in the local store.
180
+ * Make `ActiveSupport::Logger` `#freeze`-friendly.
97
181
 
98
- *Jean Boussier*
182
+ *Joshua Young*
99
183
 
100
- * Fix execution wrapping to report all exceptions, including `Exception`.
184
+ * Make `ActiveSupport::Gzip.compress` deterministic based on input.
101
185
 
102
- If a more serious error like `SystemStackError` or `NoMemoryError` happens,
103
- the error reporter should be able to report these kinds of exceptions.
186
+ `ActiveSupport::Gzip.compress` used to include a timestamp in the output,
187
+ causing consecutive calls with the same input data to have different output
188
+ if called during different seconds. It now always sets the timestamp to `0`
189
+ so that the output is identical for any given input.
104
190
 
105
- *Gannon McGibbon*
191
+ *Rob Brackett*
106
192
 
107
- * Fix `RedisCacheStore` and `MemCacheStore` to also handle connection pool related errors.
193
+ * Given an array of `Thread::Backtrace::Location` objects, the new method
194
+ `ActiveSupport::BacktraceCleaner#clean_locations` returns an array with the
195
+ clean ones:
108
196
 
109
- These errors are rescued and reported to `Rails.error`.
197
+ ```ruby
198
+ clean_locations = backtrace_cleaner.clean_locations(caller_locations)
199
+ ```
110
200
 
111
- *Jean Boussier*
201
+ Filters and silencers receive strings as usual. However, the `path`
202
+ attributes of the locations in the returned array are the original,
203
+ unfiltered ones, since locations are immutable.
112
204
 
113
- * Fix `ActiveSupport::Cache#read_multi` to respect version expiry when using local cache.
205
+ *Xavier Noria*
114
206
 
115
- *zzak*
207
+ * Improve `CurrentAttributes` and `ExecutionContext` state managment in test cases.
116
208
 
117
- * Fix `ActiveSupport::MessageVerifier` and `ActiveSupport::MessageEncryptor` configuration of `on_rotation` callback.
209
+ Previously these two global state would be entirely cleared out whenever calling
210
+ into code that is wrapped by the Rails executor, typically Action Controller or
211
+ Active Job helpers:
118
212
 
119
213
  ```ruby
120
- verifier.rotate(old_secret).on_rotation { ... }
214
+ test "#index works" do
215
+ CurrentUser.id = 42
216
+ get :index
217
+ CurrentUser.id == nil
218
+ end
121
219
  ```
122
220
 
123
- Now both work as documented.
221
+ Now re-entering the executor properly save and restore that state.
124
222
 
125
223
  *Jean Boussier*
126
224
 
127
- * Fix `ActiveSupport::MessageVerifier` to always be able to verify both URL-safe and URL-unsafe payloads.
128
-
129
- This is to allow transitioning seemlessly from either configuration without immediately invalidating
130
- all previously generated signed messages.
131
-
132
- *Jean Boussier*, *Florent Beaurain*, *Ali Sepehri*
133
-
134
- * Fix `cache.fetch` to honor the provided expiry when `:race_condition_ttl` is used.
135
-
136
- ```ruby
137
- cache.fetch("key", expires_in: 1.hour, race_condition_ttl: 5.second) do
138
- "something"
139
- end
140
- ```
225
+ * The new method `ActiveSupport::BacktraceCleaner#first_clean_location`
226
+ returns the first clean location of the caller's call stack, or `nil`.
227
+ Locations are `Thread::Backtrace::Location` objects. Useful when you want to
228
+ report the application-level location where something happened as an object.
141
229
 
142
- In the above example, the final cache entry would have a 10 seconds TTL instead
143
- of the requested 1 hour.
230
+ *Xavier Noria*
144
231
 
145
- *Dhia*
232
+ * FileUpdateChecker and EventedFileUpdateChecker ignore changes in Gem.path now.
146
233
 
147
- * Better handle procs with splat arguments in `set_callback`.
234
+ *Ermolaev Andrey*, *zzak*
148
235
 
149
- *Radamés Roriz*
236
+ * The new method `ActiveSupport::BacktraceCleaner#first_clean_frame` returns
237
+ the first clean frame of the caller's backtrace, or `nil`. Useful when you
238
+ want to report the application-level frame where something happened as a
239
+ string.
150
240
 
151
- * Fix `String#mb_chars` to not mutate the receiver.
241
+ *Xavier Noria*
152
242
 
153
- Previously it would call `force_encoding` on the receiver,
154
- now it dups the receiver first.
243
+ * Always clear `CurrentAttributes` instances.
155
244
 
156
- *Jean Boussier*
245
+ Previously `CurrentAttributes` instance would be reset at the end of requests.
246
+ Meaning its attributes would be re-initialized.
157
247
 
158
- * Improve `ErrorSubscriber` to also mark error causes as reported.
248
+ This is problematic because it assume these objects don't hold any state
249
+ other than their declared attribute, which isn't always the case, and
250
+ can lead to state leak across request.
159
251
 
160
- This avoid some cases of errors being reported twice, notably in views because of how
161
- errors are wrapped in `ActionView::Template::Error`.
252
+ Now `CurrentAttributes` instances are abandoned at the end of a request,
253
+ and a new instance is created at the start of the next request.
162
254
 
163
- *Jean Boussier*
255
+ *Jean Boussier*, *Janko Marohnić*
164
256
 
165
- * Fix `Module#module_parent_name` to return the correct name after the module has been named.
257
+ * Add public API for `before_fork_hook` in parallel testing.
166
258
 
167
- When called on an anonymous module, the return value wouldn't change after the module was given a name
168
- later by being assigned to a constant.
259
+ Introduces a public API for calling the before fork hooks implemented by parallel testing.
169
260
 
170
261
  ```ruby
171
- mod = Module.new
172
- mod.module_parent_name # => "Object"
173
- MyModule::Something = mod
174
- mod.module_parent_name # => "MyModule"
262
+ parallelize_before_fork do
263
+ # perform an action before test processes are forked
264
+ end
175
265
  ```
176
266
 
177
- *Jean Boussier*
267
+ *Eileen M. Uchitelle*
178
268
 
269
+ * Implement ability to skip creating parallel testing databases.
179
270
 
180
- ## Rails 8.0.1 (December 13, 2024) ##
271
+ With parallel testing, Rails will create a database per process. If this isn't
272
+ desirable or you would like to implement databases handling on your own, you can
273
+ now turn off this default behavior.
181
274
 
182
- * Fix a bug in `ERB::Util.tokenize` that causes incorrect tokenization when ERB tags are preceeded by multibyte characters.
275
+ To skip creating a database per process, you can change it via the
276
+ `parallelize` method:
183
277
 
184
- *Martin Emde*
278
+ ```ruby
279
+ parallelize(workers: 10, parallelize_databases: false)
280
+ ```
185
281
 
186
- * Restore the ability to decorate methods generated by `class_attribute`.
282
+ or via the application configuration:
187
283
 
188
- It always has been complicated to use Module#prepend or an alias method chain
189
- to decorate methods defined by `class_attribute`, but became even harder in 8.0.
284
+ ```ruby
285
+ config.active_support.parallelize_databases = false
286
+ ```
190
287
 
191
- This capability is now supported for both reader and writer methods.
288
+ *Eileen M. Uchitelle*
192
289
 
193
- *Jean Boussier*
290
+ * Allow to configure maximum cache key sizes
194
291
 
292
+ When the key exceeds the configured limit (250 bytes by default), it will be truncated and
293
+ the digest of the rest of the key appended to it.
195
294
 
196
- ## Rails 8.0.0.1 (December 10, 2024) ##
295
+ Note that previously `ActiveSupport::Cache::RedisCacheStore` allowed up to 1kb cache keys before
296
+ truncation, which is now reduced to 250 bytes.
197
297
 
198
- * No changes.
298
+ ```ruby
299
+ config.cache_store = :redis_cache_store, { max_key_size: 64 }
300
+ ```
199
301
 
302
+ *fatkodima*
200
303
 
201
- ## Rails 8.0.0 (November 07, 2024) ##
304
+ * Use `UNLINK` command instead of `DEL` in `ActiveSupport::Cache::RedisCacheStore` for non-blocking deletion.
202
305
 
203
- * No changes.
306
+ *Aron Roh*
204
307
 
308
+ * Add `Cache#read_counter` and `Cache#write_counter`
205
309
 
206
- ## Rails 8.0.0.rc2 (October 30, 2024) ##
310
+ ```ruby
311
+ Rails.cache.write_counter("foo", 1)
312
+ Rails.cache.read_counter("foo") # => 1
313
+ Rails.cache.increment("foo")
314
+ Rails.cache.read_counter("foo") # => 2
315
+ ```
207
316
 
208
- * No changes.
317
+ *Alex Ghiculescu*
209
318
 
319
+ * Introduce ActiveSupport::Testing::ErrorReporterAssertions#capture_error_reports
210
320
 
211
- ## Rails 8.0.0.rc1 (October 19, 2024) ##
321
+ Captures all reported errors from within the block that match the given
322
+ error class.
212
323
 
213
- * Remove deprecated support to passing an array of strings to `ActiveSupport::Deprecation#warn`.
324
+ ```ruby
325
+ reports = capture_error_reports(IOError) do
326
+ Rails.error.report(IOError.new("Oops"))
327
+ Rails.error.report(IOError.new("Oh no"))
328
+ Rails.error.report(StandardError.new)
329
+ end
214
330
 
215
- *Rafael Mendonça França*
331
+ assert_equal 2, reports.size
332
+ assert_equal "Oops", reports.first.error.message
333
+ assert_equal "Oh no", reports.last.error.message
334
+ ```
216
335
 
217
- * Remove deprecated support to setting `attr_internal_naming_format` with a `@` prefix.
336
+ *Andrew Novoselac*
218
337
 
219
- *Rafael Mendonça França*
338
+ * Introduce ActiveSupport::ErrorReporter#add_middleware
220
339
 
221
- * Remove deprecated `ActiveSupport::ProxyObject`.
340
+ When reporting an error, the error context middleware will be called with the reported error
341
+ and base execution context. The stack may mutate the context hash. The mutated context will
342
+ then be passed to error subscribers. Middleware receives the same parameters as `ErrorReporter#report`.
222
343
 
223
- *Rafael Mendonça França*
344
+ *Andrew Novoselac*, *Sam Schmidt*
224
345
 
225
- * Don't execute i18n watcher on boot. It shouldn't catch any file changes initially,
226
- and unnecessarily slows down boot of applications with lots of translations.
346
+ * Change execution wrapping to report all exceptions, including `Exception`.
227
347
 
228
- *Gannon McGibbon*, *David Stosik*
348
+ If a more serious error like `SystemStackError` or `NoMemoryError` happens,
349
+ the error reporter should be able to report these kinds of exceptions.
229
350
 
230
- * Fix `ActiveSupport::HashWithIndifferentAccess#stringify_keys` to stringify all keys not just symbols.
351
+ *Gannon McGibbon*
231
352
 
232
- Previously:
353
+ * `ActiveSupport::Testing::Parallelization.before_fork_hook` allows declaration of callbacks that
354
+ are invoked immediately before forking test workers.
233
355
 
234
- ```ruby
235
- { 1 => 2 }.with_indifferent_access.stringify_keys[1] # => 2
236
- ```
356
+ *Mike Dalessio*
237
357
 
238
- After this change:
358
+ * Allow the `#freeze_time` testing helper to accept a date or time argument.
239
359
 
240
360
  ```ruby
241
- { 1 => 2 }.with_indifferent_access.stringify_keys["1"] # => 2
361
+ Time.current # => Sun, 09 Jul 2024 15:34:49 EST -05:00
362
+ freeze_time Time.current + 1.day
363
+ sleep 1
364
+ Time.current # => Mon, 10 Jul 2024 15:34:49 EST -05:00
242
365
  ```
243
366
 
244
- This change can be seen as a bug fix, but since it behaved like this for a very long time, we're deciding
245
- to not backport the fix and to make the change in a major release.
246
-
247
- *Jean Boussier*
367
+ *Joshua Young*
248
368
 
249
- ## Rails 8.0.0.beta1 (September 26, 2024) ##
369
+ * `ActiveSupport::JSON` now accepts options
250
370
 
251
- * Include options when instrumenting `ActiveSupport::Cache::Store#delete` and `ActiveSupport::Cache::Store#delete_multi`.
371
+ It is now possible to pass options to `ActiveSupport::JSON`:
372
+ ```ruby
373
+ ActiveSupport::JSON.decode('{"key": "value"}', symbolize_names: true) # => { key: "value" }
374
+ ```
252
375
 
253
- *Adam Renberg Tamm*
376
+ *matthaigh27*
254
377
 
255
- * Print test names when running `rails test -v` for parallel tests.
378
+ * `ActiveSupport::Testing::NotificationAssertions`'s `assert_notification` now matches against payload subsets by default.
256
379
 
257
- *John Hawthorn*, *Abeid Ahmed*
380
+ Previously the following assertion would fail due to excess key vals in the notification payload. Now with payload subset matching, it will pass.
258
381
 
259
- * Deprecate `Benchmark.ms` core extension.
382
+ ```ruby
383
+ assert_notification("post.submitted", title: "Cool Post") do
384
+ ActiveSupport::Notifications.instrument("post.submitted", title: "Cool Post", body: "Cool Body")
385
+ end
386
+ ```
260
387
 
261
- The `benchmark` gem will become bundled in Ruby 3.5
388
+ Additionally, you can now persist a matched notification for more customized assertions.
262
389
 
263
- *Earlopain*
390
+ ```ruby
391
+ notification = assert_notification("post.submitted", title: "Cool Post") do
392
+ ActiveSupport::Notifications.instrument("post.submitted", title: "Cool Post", body: Body.new("Cool Body"))
393
+ end
264
394
 
265
- * `ActiveSupport::TimeWithZone#inspect` now uses ISO 8601 style time like `Time#inspect`
395
+ assert_instance_of(Body, notification.payload[:body])
396
+ ```
266
397
 
267
- *John Hawthorn*
398
+ *Nicholas La Roux*
268
399
 
269
- * `ActiveSupport::ErrorReporter#report` now assigns a backtrace to unraised exceptions.
400
+ * Deprecate `String#mb_chars` and `ActiveSupport::Multibyte::Chars`.
270
401
 
271
- Previously reporting an un-raised exception would result in an error report without
272
- a backtrace. Now it automatically generates one.
402
+ These APIs are a relic of the Ruby 1.8 days when Ruby strings weren't encoding
403
+ aware. There is no legitimate reasons to need these APIs today.
273
404
 
274
405
  *Jean Boussier*
275
406
 
276
- * Add `escape_html_entities` option to `ActiveSupport::JSON.encode`.
407
+ * Deprecate `ActiveSupport::Configurable`
277
408
 
278
- This allows for overriding the global configuration found at
279
- `ActiveSupport.escape_html_entities_in_json` for specific calls to `to_json`.
409
+ *Sean Doyle*
280
410
 
281
- This should be usable from controllers in the following manner:
282
- ```ruby
283
- class MyController < ApplicationController
284
- def index
285
- render json: { hello: "world" }, escape_html_entities: false
286
- end
287
- end
288
- ```
411
+ * `nil.to_query("key")` now returns `key`.
289
412
 
290
- *Nigel Baillie*
413
+ Previously it would return `key=`, preventing round tripping with `Rack::Utils.parse_nested_query`.
291
414
 
292
- * Raise when using key which can't respond to `#to_sym` in `EncryptedConfiguration`.
415
+ *Erol Fornoles*
293
416
 
294
- As is the case when trying to use an Integer or Float as a key, which is unsupported.
417
+ * Avoid wrapping redis in a `ConnectionPool` when using `ActiveSupport::Cache::RedisCacheStore` if the `:redis`
418
+ option is already a `ConnectionPool`.
295
419
 
296
- *zzak*
420
+ *Joshua Young*
297
421
 
298
- * Deprecate addition and since between two `Time` and `ActiveSupport::TimeWithZone`.
422
+ * Alter `ERB::Util.tokenize` to return :PLAIN token with full input string when string doesn't contain ERB tags.
299
423
 
300
- Previously adding time instances together such as `10.days.ago + 10.days.ago` or `10.days.ago.since(10.days.ago)` produced a nonsensical future date. This behavior is deprecated and will be removed in Rails 8.1.
424
+ *Martin Emde*
301
425
 
302
- *Nick Schwaderer*
426
+ * Fix a bug in `ERB::Util.tokenize` that causes incorrect tokenization when ERB tags are preceded by multibyte characters.
303
427
 
304
- * Support rfc2822 format for Time#to_fs & Date#to_fs.
428
+ *Martin Emde*
305
429
 
306
- *Akshay Birajdar*
430
+ * Add `ActiveSupport::Testing::NotificationAssertions` module to help with testing `ActiveSupport::Notifications`.
307
431
 
308
- * Optimize load time for `Railtie#initialize_i18n`. Filter `I18n.load_path`s passed to the file watcher to only those
309
- under `Rails.root`. Previously the watcher would grab all available locales, including those in gems
310
- which do not require a watcher because they won't change.
432
+ *Nicholas La Roux*, *Yishu See*, *Sean Doyle*
311
433
 
312
- *Nick Schwaderer*
434
+ * `ActiveSupport::CurrentAttributes#attributes` now will return a new hash object on each call.
313
435
 
314
- * Add a `filter` option to `in_order_of` to prioritize certain values in the sorting without filtering the results
315
- by these values.
436
+ Previously, the same hash object was returned each time that method was called.
316
437
 
317
- *Igor Depolli*
438
+ *fatkodima*
318
439
 
319
- * Improve error message when using `assert_difference` or `assert_changes` with a
320
- proc by printing the proc's source code (MRI only).
440
+ * `ActiveSupport::JSON.encode` supports CIDR notation.
321
441
 
322
- *Richard Böhme*, *Jean Boussier*
442
+ Previously:
323
443
 
324
- * Add a new configuration value `:zone` for `ActiveSupport.to_time_preserves_timezone` and rename the previous `true` value to `:offset`. The new default value is `:zone`.
444
+ ```ruby
445
+ ActiveSupport::JSON.encode(IPAddr.new("172.16.0.0/24")) # => "\"172.16.0.0\""
446
+ ```
325
447
 
326
- *Jason Kim*, *John Hawthorn*
448
+ After this change:
327
449
 
328
- * Align instrumentation `payload[:key]` in ActiveSupport::Cache to follow the same pattern, with namespaced and normalized keys.
450
+ ```ruby
451
+ ActiveSupport::JSON.encode(IPAddr.new("172.16.0.0/24")) # => "\"172.16.0.0/24\""
452
+ ```
329
453
 
330
- *Frederik Erbs Spang Thomsen*
454
+ *Taketo Takashima*
331
455
 
332
- * Fix `travel_to` to set usec 0 when `with_usec` is `false` and the given argument String or DateTime.
456
+ * Make `ActiveSupport::FileUpdateChecker` faster when checking many file-extensions.
333
457
 
334
- *mopp*
458
+ *Jonathan del Strother*
335
459
 
336
- Please check [7-2-stable](https://github.com/rails/rails/blob/7-2-stable/activesupport/CHANGELOG.md) for previous changes.
460
+ Please check [8-0-stable](https://github.com/rails/rails/blob/8-0-stable/activesupport/CHANGELOG.md) for previous changes.