activesupport 6.0.0 → 6.1.3

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 (152) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +381 -349
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +2 -2
  5. data/lib/active_support.rb +13 -1
  6. data/lib/active_support/array_inquirer.rb +4 -2
  7. data/lib/active_support/backtrace_cleaner.rb +3 -4
  8. data/lib/active_support/benchmarkable.rb +1 -1
  9. data/lib/active_support/cache.rb +101 -59
  10. data/lib/active_support/cache/file_store.rb +11 -11
  11. data/lib/active_support/cache/mem_cache_store.rb +34 -33
  12. data/lib/active_support/cache/memory_store.rb +52 -31
  13. data/lib/active_support/cache/null_store.rb +3 -3
  14. data/lib/active_support/cache/redis_cache_store.rb +38 -33
  15. data/lib/active_support/cache/strategy/local_cache.rb +41 -26
  16. data/lib/active_support/callbacks.rb +65 -59
  17. data/lib/active_support/concern.rb +46 -2
  18. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
  19. data/lib/active_support/concurrency/share_lock.rb +0 -1
  20. data/lib/active_support/configurable.rb +3 -3
  21. data/lib/active_support/configuration_file.rb +46 -0
  22. data/lib/active_support/core_ext.rb +1 -1
  23. data/lib/active_support/core_ext/array/conversions.rb +5 -5
  24. data/lib/active_support/core_ext/benchmark.rb +2 -2
  25. data/lib/active_support/core_ext/class/attribute.rb +34 -44
  26. data/lib/active_support/core_ext/class/subclasses.rb +17 -38
  27. data/lib/active_support/core_ext/date/conversions.rb +2 -1
  28. data/lib/active_support/core_ext/date_and_time/calculations.rb +13 -0
  29. data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
  30. data/lib/active_support/core_ext/date_and_time/zones.rb +0 -1
  31. data/lib/active_support/core_ext/date_time/conversions.rb +0 -1
  32. data/lib/active_support/core_ext/enumerable.rb +76 -4
  33. data/lib/active_support/core_ext/hash/conversions.rb +3 -3
  34. data/lib/active_support/core_ext/hash/deep_transform_values.rb +1 -1
  35. data/lib/active_support/core_ext/hash/except.rb +1 -1
  36. data/lib/active_support/core_ext/hash/keys.rb +1 -1
  37. data/lib/active_support/core_ext/hash/slice.rb +3 -2
  38. data/lib/active_support/core_ext/load_error.rb +1 -1
  39. data/lib/active_support/core_ext/marshal.rb +2 -0
  40. data/lib/active_support/core_ext/module/attr_internal.rb +2 -2
  41. data/lib/active_support/core_ext/module/attribute_accessors.rb +23 -29
  42. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +8 -4
  43. data/lib/active_support/core_ext/module/concerning.rb +8 -2
  44. data/lib/active_support/core_ext/module/delegation.rb +46 -29
  45. data/lib/active_support/core_ext/module/introspection.rb +2 -25
  46. data/lib/active_support/core_ext/name_error.rb +29 -2
  47. data/lib/active_support/core_ext/numeric/conversions.rb +22 -18
  48. data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
  49. data/lib/active_support/core_ext/object/json.rb +13 -2
  50. data/lib/active_support/core_ext/object/try.rb +4 -2
  51. data/lib/active_support/core_ext/range/compare_range.rb +15 -3
  52. data/lib/active_support/core_ext/range/each.rb +0 -1
  53. data/lib/active_support/core_ext/range/include_time_with_zone.rb +8 -3
  54. data/lib/active_support/core_ext/regexp.rb +8 -1
  55. data/lib/active_support/core_ext/string/access.rb +5 -24
  56. data/lib/active_support/core_ext/string/conversions.rb +1 -0
  57. data/lib/active_support/core_ext/string/inflections.rb +38 -4
  58. data/lib/active_support/core_ext/string/inquiry.rb +1 -0
  59. data/lib/active_support/core_ext/string/multibyte.rb +2 -2
  60. data/lib/active_support/core_ext/string/output_safety.rb +12 -11
  61. data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -2
  62. data/lib/active_support/core_ext/symbol.rb +3 -0
  63. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +14 -0
  64. data/lib/active_support/core_ext/time/calculations.rb +27 -3
  65. data/lib/active_support/core_ext/time/conversions.rb +2 -0
  66. data/lib/active_support/core_ext/uri.rb +5 -1
  67. data/lib/active_support/current_attributes.rb +7 -2
  68. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  69. data/lib/active_support/dependencies.rb +42 -20
  70. data/lib/active_support/dependencies/zeitwerk_integration.rb +9 -2
  71. data/lib/active_support/deprecation.rb +6 -1
  72. data/lib/active_support/deprecation/behaviors.rb +15 -2
  73. data/lib/active_support/deprecation/disallowed.rb +56 -0
  74. data/lib/active_support/deprecation/instance_delegator.rb +0 -1
  75. data/lib/active_support/deprecation/method_wrappers.rb +13 -6
  76. data/lib/active_support/deprecation/proxy_wrappers.rb +6 -2
  77. data/lib/active_support/deprecation/reporting.rb +50 -7
  78. data/lib/active_support/descendants_tracker.rb +6 -3
  79. data/lib/active_support/duration.rb +86 -35
  80. data/lib/active_support/duration/iso8601_parser.rb +0 -1
  81. data/lib/active_support/duration/iso8601_serializer.rb +15 -10
  82. data/lib/active_support/encrypted_file.rb +20 -3
  83. data/lib/active_support/environment_inquirer.rb +20 -0
  84. data/lib/active_support/evented_file_update_checker.rb +69 -134
  85. data/lib/active_support/file_update_checker.rb +0 -1
  86. data/lib/active_support/fork_tracker.rb +62 -0
  87. data/lib/active_support/gem_version.rb +2 -2
  88. data/lib/active_support/hash_with_indifferent_access.rb +43 -24
  89. data/lib/active_support/i18n_railtie.rb +15 -16
  90. data/lib/active_support/inflector/inflections.rb +1 -3
  91. data/lib/active_support/inflector/methods.rb +36 -33
  92. data/lib/active_support/inflector/transliterate.rb +4 -4
  93. data/lib/active_support/json/decoding.rb +4 -5
  94. data/lib/active_support/json/encoding.rb +5 -1
  95. data/lib/active_support/key_generator.rb +1 -1
  96. data/lib/active_support/lazy_load_hooks.rb +0 -1
  97. data/lib/active_support/locale/en.rb +4 -2
  98. data/lib/active_support/locale/en.yml +7 -3
  99. data/lib/active_support/log_subscriber.rb +8 -1
  100. data/lib/active_support/logger.rb +2 -2
  101. data/lib/active_support/logger_silence.rb +2 -26
  102. data/lib/active_support/logger_thread_safe_level.rb +34 -12
  103. data/lib/active_support/message_encryptor.rb +5 -8
  104. data/lib/active_support/message_verifier.rb +7 -7
  105. data/lib/active_support/messages/metadata.rb +11 -2
  106. data/lib/active_support/messages/rotation_configuration.rb +2 -1
  107. data/lib/active_support/messages/rotator.rb +10 -9
  108. data/lib/active_support/multibyte/chars.rb +5 -44
  109. data/lib/active_support/multibyte/unicode.rb +9 -84
  110. data/lib/active_support/notifications.rb +32 -5
  111. data/lib/active_support/notifications/fanout.rb +23 -8
  112. data/lib/active_support/notifications/instrumenter.rb +7 -16
  113. data/lib/active_support/number_helper.rb +33 -14
  114. data/lib/active_support/number_helper/number_converter.rb +5 -6
  115. data/lib/active_support/number_helper/number_to_currency_converter.rb +2 -7
  116. data/lib/active_support/number_helper/number_to_delimited_converter.rb +0 -1
  117. data/lib/active_support/number_helper/number_to_human_converter.rb +1 -2
  118. data/lib/active_support/number_helper/number_to_human_size_converter.rb +1 -2
  119. data/lib/active_support/number_helper/number_to_phone_converter.rb +0 -1
  120. data/lib/active_support/number_helper/number_to_rounded_converter.rb +3 -4
  121. data/lib/active_support/number_helper/rounding_helper.rb +12 -28
  122. data/lib/active_support/option_merger.rb +22 -3
  123. data/lib/active_support/ordered_hash.rb +1 -1
  124. data/lib/active_support/ordered_options.rb +13 -3
  125. data/lib/active_support/parameter_filter.rb +17 -13
  126. data/lib/active_support/per_thread_registry.rb +1 -1
  127. data/lib/active_support/rails.rb +1 -4
  128. data/lib/active_support/railtie.rb +23 -1
  129. data/lib/active_support/rescuable.rb +4 -4
  130. data/lib/active_support/secure_compare_rotator.rb +51 -0
  131. data/lib/active_support/security_utils.rb +19 -12
  132. data/lib/active_support/string_inquirer.rb +4 -3
  133. data/lib/active_support/subscriber.rb +12 -7
  134. data/lib/active_support/tagged_logging.rb +29 -4
  135. data/lib/active_support/testing/assertions.rb +18 -11
  136. data/lib/active_support/testing/parallelization.rb +12 -89
  137. data/lib/active_support/testing/parallelization/server.rb +78 -0
  138. data/lib/active_support/testing/parallelization/worker.rb +100 -0
  139. data/lib/active_support/testing/stream.rb +0 -1
  140. data/lib/active_support/testing/time_helpers.rb +40 -5
  141. data/lib/active_support/time_with_zone.rb +67 -43
  142. data/lib/active_support/values/time_zone.rb +20 -10
  143. data/lib/active_support/xml_mini.rb +0 -1
  144. data/lib/active_support/xml_mini/jdom.rb +0 -1
  145. data/lib/active_support/xml_mini/rexml.rb +8 -1
  146. metadata +39 -38
  147. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -5
  148. data/lib/active_support/core_ext/hash/compact.rb +0 -5
  149. data/lib/active_support/core_ext/hash/transform_values.rb +0 -5
  150. data/lib/active_support/core_ext/module/reachable.rb +0 -6
  151. data/lib/active_support/core_ext/numeric/inquiry.rb +0 -5
  152. data/lib/active_support/core_ext/range/include_range.rb +0 -9
@@ -54,7 +54,6 @@ module ActiveSupport
54
54
  end
55
55
 
56
56
  private
57
-
58
57
  def with_execution_control(name, block, once)
59
58
  unless @run_once[name].include?(block)
60
59
  @run_once[name] << block if once
@@ -4,7 +4,8 @@
4
4
  en: {
5
5
  number: {
6
6
  nth: {
7
- ordinals: lambda do |_key, number:, **_options|
7
+ ordinals: lambda do |_key, options|
8
+ number = options[:number]
8
9
  case number
9
10
  when 1; "st"
10
11
  when 2; "nd"
@@ -22,7 +23,8 @@
22
23
  end
23
24
  end,
24
25
 
25
- ordinalized: lambda do |_key, number:, **_options|
26
+ ordinalized: lambda do |_key, options|
27
+ number = options[:number]
26
28
  "#{number}#{ActiveSupport::Inflector.ordinal(number)}"
27
29
  end
28
30
  }
@@ -44,10 +44,12 @@ en:
44
44
  delimiter: ","
45
45
  # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00)
46
46
  precision: 3
47
+ # Determine how rounding is performed (see BigDecimal::mode)
48
+ round_mode: !ruby/sym default
47
49
  # If set to true, precision will mean the number of significant digits instead
48
50
  # of the number of decimal digits (1234 with precision 2 becomes 1200, 1.23543 becomes 1.2)
49
51
  significant: false
50
- # If set, the zeros after the decimal separator will always be stripped (eg.: 1.200 will be 1.2)
52
+ # If set, the zeros after the decimal separator will always be stripped (e.g.: 1.200 will be 1.2)
51
53
  strip_insignificant_zeros: false
52
54
 
53
55
  # Used in NumberHelper.number_to_currency()
@@ -56,10 +58,11 @@ en:
56
58
  # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00)
57
59
  format: "%u%n"
58
60
  unit: "$"
59
- # These five are to override number.format and are optional
61
+ # These six are to override number.format and are optional
60
62
  separator: "."
61
63
  delimiter: ","
62
64
  precision: 2
65
+ # round_mode:
63
66
  significant: false
64
67
  strip_insignificant_zeros: false
65
68
 
@@ -87,10 +90,11 @@ en:
87
90
  # Used in NumberHelper.number_to_human_size() and NumberHelper.number_to_human()
88
91
  human:
89
92
  format:
90
- # These five are to override number.format and are optional
93
+ # These six are to override number.format and are optional
91
94
  # separator:
92
95
  delimiter: ""
93
96
  precision: 3
97
+ # round_mode:
94
98
  significant: true
95
99
  strip_insignificant_zeros: true
96
100
  # Used in number_to_human_size()
@@ -29,6 +29,9 @@ module ActiveSupport
29
29
  # subscriber, the line above should be called after your
30
30
  # <tt>ActiveRecord::LogSubscriber</tt> definition.
31
31
  #
32
+ # A logger also needs to be set with <tt>ActiveRecord::LogSubscriber.logger=</tt>.
33
+ # This is assigned automatically in a Rails environment.
34
+ #
32
35
  # After configured, whenever a <tt>"sql.active_record"</tt> notification is published,
33
36
  # it will properly dispatch the event
34
37
  # (<tt>ActiveSupport::Notifications::Event</tt>) to the sql method.
@@ -93,6 +96,11 @@ module ActiveSupport
93
96
  def flush_all!
94
97
  logger.flush if logger.respond_to?(:flush)
95
98
  end
99
+
100
+ private
101
+ def fetch_public_methods(subscriber, inherit_all)
102
+ subscriber.public_methods(inherit_all) - LogSubscriber.public_instance_methods(true)
103
+ end
96
104
  end
97
105
 
98
106
  def logger
@@ -112,7 +120,6 @@ module ActiveSupport
112
120
  end
113
121
 
114
122
  private
115
-
116
123
  %w(info debug warn error fatal unknown).each do |level|
117
124
  class_eval <<-METHOD, __FILE__, __LINE__ + 1
118
125
  def #{level}(progname = nil, &block)
@@ -14,7 +14,7 @@ module ActiveSupport
14
14
  # ActiveSupport::Logger.logger_outputs_to?(logger, STDOUT)
15
15
  # # => true
16
16
  def self.logger_outputs_to?(logger, *sources)
17
- logdev = logger.instance_variable_get("@logdev")
17
+ logdev = logger.instance_variable_get(:@logdev)
18
18
  logger_source = logdev.dev if logdev.respond_to?(:dev)
19
19
  sources.any? { |source| source == logger_source }
20
20
  end
@@ -77,7 +77,7 @@ module ActiveSupport
77
77
  end
78
78
  end
79
79
 
80
- def initialize(*args)
80
+ def initialize(*args, **kwargs)
81
81
  super
82
82
  @formatter = SimpleFormatter.new
83
83
  end
@@ -4,19 +4,6 @@ require "active_support/concern"
4
4
  require "active_support/core_ext/module/attribute_accessors"
5
5
  require "active_support/logger_thread_safe_level"
6
6
 
7
- module LoggerSilence
8
- extend ActiveSupport::Concern
9
-
10
- included do
11
- ActiveSupport::Deprecation.warn(
12
- "Including LoggerSilence is deprecated and will be removed in Rails 6.1. " \
13
- "Please use `ActiveSupport::LoggerSilence` instead"
14
- )
15
-
16
- include ActiveSupport::LoggerSilence
17
- end
18
- end
19
-
20
7
  module ActiveSupport
21
8
  module LoggerSilence
22
9
  extend ActiveSupport::Concern
@@ -27,19 +14,8 @@ module ActiveSupport
27
14
  end
28
15
 
29
16
  # Silences the logger for the duration of the block.
30
- def silence(temporary_level = Logger::ERROR)
31
- if silencer
32
- begin
33
- old_local_level = local_level
34
- self.local_level = temporary_level
35
-
36
- yield self
37
- ensure
38
- self.local_level = old_local_level
39
- end
40
- else
41
- yield self
42
- end
17
+ def silence(severity = Logger::ERROR)
18
+ silencer ? log_at(severity) { yield self } : yield(self)
43
19
  end
44
20
  end
45
21
  end
@@ -21,13 +21,6 @@ module ActiveSupport
21
21
  EOT
22
22
  end
23
23
 
24
- def after_initialize
25
- ActiveSupport::Deprecation.warn(
26
- "Logger don't need to call #after_initialize directly anymore. It will be deprecated without replacement in " \
27
- "Rails 6.1."
28
- )
29
- end
30
-
31
24
  def local_log_id
32
25
  Fiber.current.__id__
33
26
  end
@@ -37,10 +30,15 @@ module ActiveSupport
37
30
  end
38
31
 
39
32
  def local_level=(level)
40
- if level
33
+ case level
34
+ when Integer
41
35
  self.class.local_levels[local_log_id] = level
42
- else
36
+ when Symbol
37
+ self.class.local_levels[local_log_id] = Logger::Severity.const_get(level.to_s.upcase)
38
+ when nil
43
39
  self.class.local_levels.delete(local_log_id)
40
+ else
41
+ raise ArgumentError, "Invalid log level: #{level.inspect}"
44
42
  end
45
43
  end
46
44
 
@@ -48,9 +46,33 @@ module ActiveSupport
48
46
  local_level || super
49
47
  end
50
48
 
51
- def add(severity, message = nil, progname = nil, &block) # :nodoc:
52
- return true if @logdev.nil? || (severity || UNKNOWN) < level
53
- super
49
+ # Change the thread-local level for the duration of the given block.
50
+ def log_at(level)
51
+ old_local_level, self.local_level = local_level, level
52
+ yield
53
+ ensure
54
+ self.local_level = old_local_level
55
+ end
56
+
57
+ # Redefined to check severity against #level, and thus the thread-local level, rather than +@level+.
58
+ # FIXME: Remove when the minimum Ruby version supports overriding Logger#level.
59
+ def add(severity, message = nil, progname = nil, &block) #:nodoc:
60
+ severity ||= UNKNOWN
61
+ progname ||= @progname
62
+
63
+ return true if @logdev.nil? || severity < level
64
+
65
+ if message.nil?
66
+ if block_given?
67
+ message = yield
68
+ else
69
+ message = progname
70
+ progname = @progname
71
+ end
72
+ end
73
+
74
+ @logdev.write \
75
+ format_message(format_severity(severity), Time.now, progname, message)
54
76
  end
55
77
  end
56
78
  end
@@ -2,7 +2,6 @@
2
2
 
3
3
  require "openssl"
4
4
  require "base64"
5
- require "active_support/core_ext/array/extract_options"
6
5
  require "active_support/core_ext/module/attribute_accessors"
7
6
  require "active_support/message_verifier"
8
7
  require "active_support/messages/metadata"
@@ -134,15 +133,13 @@ module ActiveSupport
134
133
  # * <tt>:digest</tt> - String of digest to use for signing. Default is
135
134
  # +SHA1+. Ignored when using an AEAD cipher like 'aes-256-gcm'.
136
135
  # * <tt>:serializer</tt> - Object serializer to use. Default is +Marshal+.
137
- def initialize(secret, *signature_key_or_options)
138
- options = signature_key_or_options.extract_options!
139
- sign_secret = signature_key_or_options.first
136
+ def initialize(secret, sign_secret = nil, cipher: nil, digest: nil, serializer: nil)
140
137
  @secret = secret
141
138
  @sign_secret = sign_secret
142
- @cipher = options[:cipher] || self.class.default_cipher
143
- @digest = options[:digest] || "SHA1" unless aead_mode?
139
+ @cipher = cipher || self.class.default_cipher
140
+ @digest = digest || "SHA1" unless aead_mode?
144
141
  @verifier = resolve_verifier
145
- @serializer = options[:serializer] || Marshal
142
+ @serializer = serializer || Marshal
146
143
  end
147
144
 
148
145
  # Encrypt and sign a message. We need to sign the message in order to avoid
@@ -172,7 +169,7 @@ module ActiveSupport
172
169
  iv = cipher.random_iv
173
170
  cipher.auth_data = "" if aead_mode?
174
171
 
175
- encrypted_data = cipher.update(Messages::Metadata.wrap(@serializer.dump(value), metadata_options))
172
+ encrypted_data = cipher.update(Messages::Metadata.wrap(@serializer.dump(value), **metadata_options))
176
173
  encrypted_data << cipher.final
177
174
 
178
175
  blob = "#{::Base64.strict_encode64 encrypted_data}--#{::Base64.strict_encode64 iv}"
@@ -103,11 +103,11 @@ module ActiveSupport
103
103
 
104
104
  class InvalidSignature < StandardError; end
105
105
 
106
- def initialize(secret, options = {})
106
+ def initialize(secret, digest: nil, serializer: nil)
107
107
  raise ArgumentError, "Secret should not be nil." unless secret
108
108
  @secret = secret
109
- @digest = options[:digest] || "SHA1"
110
- @serializer = options[:serializer] || Marshal
109
+ @digest = digest || "SHA1"
110
+ @serializer = serializer || Marshal
111
111
  end
112
112
 
113
113
  # Checks if a signed message could have been generated by signing an object
@@ -172,14 +172,14 @@ module ActiveSupport
172
172
  #
173
173
  # other_verifier = ActiveSupport::MessageVerifier.new 'd1ff3r3nt-s3Krit'
174
174
  # other_verifier.verify(signed_message) # => ActiveSupport::MessageVerifier::InvalidSignature
175
- def verify(*args)
176
- verified(*args) || raise(InvalidSignature)
175
+ def verify(*args, **options)
176
+ verified(*args, **options) || raise(InvalidSignature)
177
177
  end
178
178
 
179
179
  # Generates a signed message for the provided value.
180
180
  #
181
- # The message is signed with the +MessageVerifier+'s secret. Without knowing
182
- # the secret, the original value cannot be extracted from the message.
181
+ # The message is signed with the +MessageVerifier+'s secret.
182
+ # Returns Base64-encoded message joined with the generated signature.
183
183
  #
184
184
  # verifier = ActiveSupport::MessageVerifier.new 's3Krit'
185
185
  # verifier.generate 'a private message' # => "BAhJIhRwcml2YXRlLW1lc3NhZ2UGOgZFVA==--e2d724331ebdee96a10fb99b089508d1c72bd772"
@@ -6,7 +6,8 @@ module ActiveSupport
6
6
  module Messages #:nodoc:
7
7
  class Metadata #:nodoc:
8
8
  def initialize(message, expires_at = nil, purpose = nil)
9
- @message, @expires_at, @purpose = message, expires_at, purpose
9
+ @message, @purpose = message, purpose
10
+ @expires_at = expires_at.is_a?(String) ? parse_expires_at(expires_at) : expires_at
10
11
  end
11
12
 
12
13
  def as_json(options = {})
@@ -64,7 +65,15 @@ module ActiveSupport
64
65
  end
65
66
 
66
67
  def fresh?
67
- @expires_at.nil? || Time.now.utc < Time.iso8601(@expires_at)
68
+ @expires_at.nil? || Time.now.utc < @expires_at
69
+ end
70
+
71
+ def parse_expires_at(expires_at)
72
+ if ActiveSupport.use_standard_json_time_format
73
+ Time.iso8601(expires_at)
74
+ else
75
+ Time.parse(expires_at)
76
+ end
68
77
  end
69
78
  end
70
79
  end
@@ -9,7 +9,8 @@ module ActiveSupport
9
9
  @signed, @encrypted = [], []
10
10
  end
11
11
 
12
- def rotate(kind, *args)
12
+ def rotate(kind, *args, **options)
13
+ args << options unless options.empty?
13
14
  case kind
14
15
  when :signed
15
16
  @signed << args
@@ -3,11 +3,12 @@
3
3
  module ActiveSupport
4
4
  module Messages
5
5
  module Rotator # :nodoc:
6
- def initialize(*, **options)
7
- super
6
+ def initialize(*secrets, on_rotation: nil, **options)
7
+ super(*secrets, **options)
8
8
 
9
9
  @options = options
10
10
  @rotations = []
11
+ @on_rotation = on_rotation
11
12
  end
12
13
 
13
14
  def rotate(*secrets, **options)
@@ -17,28 +18,28 @@ module ActiveSupport
17
18
  module Encryptor
18
19
  include Rotator
19
20
 
20
- def decrypt_and_verify(*args, on_rotation: nil, **options)
21
+ def decrypt_and_verify(*args, on_rotation: @on_rotation, **options)
21
22
  super
22
23
  rescue MessageEncryptor::InvalidMessage, MessageVerifier::InvalidSignature
23
- run_rotations(on_rotation) { |encryptor| encryptor.decrypt_and_verify(*args, options) } || raise
24
+ run_rotations(on_rotation) { |encryptor| encryptor.decrypt_and_verify(*args, **options) } || raise
24
25
  end
25
26
 
26
27
  private
27
28
  def build_rotation(secret = @secret, sign_secret = @sign_secret, options)
28
- self.class.new(secret, sign_secret, options)
29
+ self.class.new(secret, sign_secret, **options)
29
30
  end
30
31
  end
31
32
 
32
33
  module Verifier
33
34
  include Rotator
34
35
 
35
- def verified(*args, on_rotation: nil, **options)
36
- super || run_rotations(on_rotation) { |verifier| verifier.verified(*args, options) }
36
+ def verified(*args, on_rotation: @on_rotation, **options)
37
+ super || run_rotations(on_rotation) { |verifier| verifier.verified(*args, **options) }
37
38
  end
38
39
 
39
40
  private
40
41
  def build_rotation(secret = @secret, options)
41
- self.class.new(secret, options)
42
+ self.class.new(secret, **options)
42
43
  end
43
44
  end
44
45
 
@@ -46,7 +47,7 @@ module ActiveSupport
46
47
  def run_rotations(on_rotation)
47
48
  @rotations.find do |rotation|
48
49
  if message = yield(rotation) rescue next
49
- on_rotation.call if on_rotation
50
+ on_rotation&.call
50
51
  return message
51
52
  end
52
53
  end
@@ -3,6 +3,7 @@
3
3
  require "active_support/json"
4
4
  require "active_support/core_ext/string/access"
5
5
  require "active_support/core_ext/string/behavior"
6
+ require "active_support/core_ext/symbol/starts_ends_with"
6
7
  require "active_support/core_ext/module/delegation"
7
8
 
8
9
  module ActiveSupport #:nodoc:
@@ -48,7 +49,7 @@ module ActiveSupport #:nodoc:
48
49
  alias to_s wrapped_string
49
50
  alias to_str wrapped_string
50
51
 
51
- delegate :<=>, :=~, :acts_like_string?, to: :wrapped_string
52
+ delegate :<=>, :=~, :match?, :acts_like_string?, to: :wrapped_string
52
53
 
53
54
  # Creates a new Chars instance by wrapping _string_.
54
55
  def initialize(string)
@@ -59,7 +60,7 @@ module ActiveSupport #:nodoc:
59
60
  # Forward all undefined methods to the wrapped string.
60
61
  def method_missing(method, *args, &block)
61
62
  result = @wrapped_string.__send__(method, *args, &block)
62
- if /!$/.match?(method)
63
+ if method.end_with?("!")
63
64
  self if result
64
65
  else
65
66
  result.kind_of?(String) ? chars(result) : result
@@ -73,17 +74,6 @@ module ActiveSupport #:nodoc:
73
74
  @wrapped_string.respond_to?(method, include_private)
74
75
  end
75
76
 
76
- # Returns +true+ when the proxy class can handle the string. Returns
77
- # +false+ otherwise.
78
- def self.consumes?(string)
79
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
80
- ActiveSupport::Multibyte::Chars.consumes? is deprecated and will be
81
- removed from Rails 6.1. Use string.is_utf8? instead.
82
- MSG
83
-
84
- string.encoding == Encoding::UTF_8
85
- end
86
-
87
77
  # Works just like <tt>String#split</tt>, with the exception that the items
88
78
  # in the resulting list are Chars instances instead of String. This makes
89
79
  # chaining methods easier.
@@ -122,7 +112,7 @@ module ActiveSupport #:nodoc:
122
112
  #
123
113
  # 'こんにちは'.mb_chars.limit(7).to_s # => "こん"
124
114
  def limit(limit)
125
- truncate_bytes(limit, omission: nil)
115
+ chars(@wrapped_string.truncate_bytes(limit, omission: nil))
126
116
  end
127
117
 
128
118
  # Capitalizes the first letter of every word, when possible.
@@ -134,34 +124,6 @@ module ActiveSupport #:nodoc:
134
124
  end
135
125
  alias_method :titlecase, :titleize
136
126
 
137
- # Returns the KC normalization of the string by default. NFKC is
138
- # considered the best normalization form for passing strings to databases
139
- # and validations.
140
- #
141
- # * <tt>form</tt> - The form you want to normalize in. Should be one of the following:
142
- # <tt>:c</tt>, <tt>:kc</tt>, <tt>:d</tt>, or <tt>:kd</tt>. Default is
143
- # ActiveSupport::Multibyte::Unicode.default_normalization_form
144
- def normalize(form = nil)
145
- form ||= Unicode.default_normalization_form
146
-
147
- # See https://www.unicode.org/reports/tr15, Table 1
148
- if alias_form = Unicode::NORMALIZATION_FORM_ALIASES[form]
149
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
150
- ActiveSupport::Multibyte::Chars#normalize is deprecated and will be
151
- removed from Rails 6.1. Use #unicode_normalize(:#{alias_form}) instead.
152
- MSG
153
-
154
- send(:unicode_normalize, alias_form)
155
- else
156
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
157
- ActiveSupport::Multibyte::Chars#normalize is deprecated and will be
158
- removed from Rails 6.1. Use #unicode_normalize instead.
159
- MSG
160
-
161
- raise ArgumentError, "#{form} is not a valid normalization variant", caller
162
- end
163
- end
164
-
165
127
  # Performs canonical decomposition on all the characters.
166
128
  #
167
129
  # 'é'.length # => 2
@@ -201,13 +163,12 @@ module ActiveSupport #:nodoc:
201
163
 
202
164
  %w(reverse tidy_bytes).each do |method|
203
165
  define_method("#{method}!") do |*args|
204
- @wrapped_string = send(method, *args).to_s
166
+ @wrapped_string = public_send(method, *args).to_s
205
167
  self
206
168
  end
207
169
  end
208
170
 
209
171
  private
210
-
211
172
  def chars(string)
212
173
  self.class.new(string)
213
174
  end