activesupport 7.0.4 → 7.1.5.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 (189) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1076 -230
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +6 -6
  5. data/lib/active_support/actionable_error.rb +3 -1
  6. data/lib/active_support/array_inquirer.rb +2 -0
  7. data/lib/active_support/backtrace_cleaner.rb +30 -5
  8. data/lib/active_support/benchmarkable.rb +1 -0
  9. data/lib/active_support/broadcast_logger.rb +251 -0
  10. data/lib/active_support/builder.rb +1 -1
  11. data/lib/active_support/cache/coder.rb +153 -0
  12. data/lib/active_support/cache/entry.rb +134 -0
  13. data/lib/active_support/cache/file_store.rb +37 -10
  14. data/lib/active_support/cache/mem_cache_store.rb +100 -76
  15. data/lib/active_support/cache/memory_store.rb +78 -24
  16. data/lib/active_support/cache/null_store.rb +6 -0
  17. data/lib/active_support/cache/redis_cache_store.rb +153 -141
  18. data/lib/active_support/cache/serializer_with_fallback.rb +175 -0
  19. data/lib/active_support/cache/strategy/local_cache.rb +29 -14
  20. data/lib/active_support/cache.rb +333 -253
  21. data/lib/active_support/callbacks.rb +44 -21
  22. data/lib/active_support/code_generator.rb +15 -10
  23. data/lib/active_support/concern.rb +4 -2
  24. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +42 -3
  25. data/lib/active_support/concurrency/null_lock.rb +13 -0
  26. data/lib/active_support/configurable.rb +10 -0
  27. data/lib/active_support/core_ext/array/conversions.rb +2 -1
  28. data/lib/active_support/core_ext/array.rb +0 -1
  29. data/lib/active_support/core_ext/class/subclasses.rb +13 -10
  30. data/lib/active_support/core_ext/date/calculations.rb +15 -0
  31. data/lib/active_support/core_ext/date/conversions.rb +2 -1
  32. data/lib/active_support/core_ext/date.rb +0 -1
  33. data/lib/active_support/core_ext/date_and_time/calculations.rb +10 -0
  34. data/lib/active_support/core_ext/date_time/calculations.rb +4 -0
  35. data/lib/active_support/core_ext/date_time/conversions.rb +6 -2
  36. data/lib/active_support/core_ext/date_time.rb +0 -1
  37. data/lib/active_support/core_ext/digest/uuid.rb +1 -10
  38. data/lib/active_support/core_ext/enumerable.rb +8 -75
  39. data/lib/active_support/core_ext/erb/util.rb +196 -0
  40. data/lib/active_support/core_ext/hash/conversions.rb +1 -1
  41. data/lib/active_support/core_ext/hash/deep_merge.rb +22 -14
  42. data/lib/active_support/core_ext/hash/deep_transform_values.rb +3 -3
  43. data/lib/active_support/core_ext/hash/keys.rb +3 -3
  44. data/lib/active_support/core_ext/integer/inflections.rb +12 -12
  45. data/lib/active_support/core_ext/module/attribute_accessors.rb +6 -0
  46. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +34 -16
  47. data/lib/active_support/core_ext/module/concerning.rb +6 -6
  48. data/lib/active_support/core_ext/module/delegation.rb +81 -37
  49. data/lib/active_support/core_ext/module/deprecation.rb +15 -12
  50. data/lib/active_support/core_ext/module/introspection.rb +0 -1
  51. data/lib/active_support/core_ext/numeric/bytes.rb +9 -0
  52. data/lib/active_support/core_ext/numeric/conversions.rb +2 -0
  53. data/lib/active_support/core_ext/numeric.rb +0 -1
  54. data/lib/active_support/core_ext/object/deep_dup.rb +16 -0
  55. data/lib/active_support/core_ext/object/duplicable.rb +25 -16
  56. data/lib/active_support/core_ext/object/inclusion.rb +13 -5
  57. data/lib/active_support/core_ext/object/instance_variables.rb +22 -12
  58. data/lib/active_support/core_ext/object/json.rb +16 -6
  59. data/lib/active_support/core_ext/object/to_query.rb +0 -2
  60. data/lib/active_support/core_ext/object/with.rb +44 -0
  61. data/lib/active_support/core_ext/object/with_options.rb +9 -9
  62. data/lib/active_support/core_ext/object.rb +1 -0
  63. data/lib/active_support/core_ext/pathname/blank.rb +16 -0
  64. data/lib/active_support/core_ext/pathname/existence.rb +2 -0
  65. data/lib/active_support/core_ext/pathname.rb +1 -0
  66. data/lib/active_support/core_ext/range/conversions.rb +28 -7
  67. data/lib/active_support/core_ext/range/overlap.rb +40 -0
  68. data/lib/active_support/core_ext/range.rb +1 -2
  69. data/lib/active_support/core_ext/securerandom.rb +24 -12
  70. data/lib/active_support/core_ext/string/filters.rb +20 -14
  71. data/lib/active_support/core_ext/string/indent.rb +1 -1
  72. data/lib/active_support/core_ext/string/inflections.rb +16 -9
  73. data/lib/active_support/core_ext/string/output_safety.rb +42 -174
  74. data/lib/active_support/core_ext/thread/backtrace/location.rb +12 -0
  75. data/lib/active_support/core_ext/time/calculations.rb +22 -2
  76. data/lib/active_support/core_ext/time/conversions.rb +2 -2
  77. data/lib/active_support/core_ext/time/zones.rb +7 -8
  78. data/lib/active_support/core_ext/time.rb +0 -1
  79. data/lib/active_support/current_attributes.rb +15 -6
  80. data/lib/active_support/deep_mergeable.rb +53 -0
  81. data/lib/active_support/dependencies/autoload.rb +17 -12
  82. data/lib/active_support/deprecation/behaviors.rb +65 -42
  83. data/lib/active_support/deprecation/constant_accessor.rb +5 -4
  84. data/lib/active_support/deprecation/deprecators.rb +104 -0
  85. data/lib/active_support/deprecation/disallowed.rb +6 -8
  86. data/lib/active_support/deprecation/instance_delegator.rb +31 -4
  87. data/lib/active_support/deprecation/method_wrappers.rb +6 -23
  88. data/lib/active_support/deprecation/proxy_wrappers.rb +37 -22
  89. data/lib/active_support/deprecation/reporting.rb +43 -26
  90. data/lib/active_support/deprecation.rb +32 -5
  91. data/lib/active_support/deprecator.rb +7 -0
  92. data/lib/active_support/descendants_tracker.rb +104 -132
  93. data/lib/active_support/duration/iso8601_serializer.rb +0 -2
  94. data/lib/active_support/duration.rb +2 -1
  95. data/lib/active_support/encrypted_configuration.rb +63 -11
  96. data/lib/active_support/encrypted_file.rb +16 -12
  97. data/lib/active_support/environment_inquirer.rb +22 -2
  98. data/lib/active_support/error_reporter/test_helper.rb +15 -0
  99. data/lib/active_support/error_reporter.rb +121 -35
  100. data/lib/active_support/evented_file_update_checker.rb +17 -2
  101. data/lib/active_support/execution_wrapper.rb +4 -4
  102. data/lib/active_support/file_update_checker.rb +4 -2
  103. data/lib/active_support/fork_tracker.rb +10 -2
  104. data/lib/active_support/gem_version.rb +4 -4
  105. data/lib/active_support/gzip.rb +2 -0
  106. data/lib/active_support/hash_with_indifferent_access.rb +35 -17
  107. data/lib/active_support/html_safe_translation.rb +16 -6
  108. data/lib/active_support/i18n.rb +1 -1
  109. data/lib/active_support/i18n_railtie.rb +20 -13
  110. data/lib/active_support/inflector/inflections.rb +2 -0
  111. data/lib/active_support/inflector/methods.rb +28 -18
  112. data/lib/active_support/inflector/transliterate.rb +3 -1
  113. data/lib/active_support/isolated_execution_state.rb +26 -22
  114. data/lib/active_support/json/decoding.rb +2 -1
  115. data/lib/active_support/json/encoding.rb +25 -43
  116. data/lib/active_support/key_generator.rb +9 -1
  117. data/lib/active_support/lazy_load_hooks.rb +7 -5
  118. data/lib/active_support/locale/en.yml +2 -0
  119. data/lib/active_support/log_subscriber.rb +85 -33
  120. data/lib/active_support/logger.rb +9 -60
  121. data/lib/active_support/logger_thread_safe_level.rb +10 -24
  122. data/lib/active_support/message_encryptor.rb +197 -53
  123. data/lib/active_support/message_encryptors.rb +141 -0
  124. data/lib/active_support/message_pack/cache_serializer.rb +23 -0
  125. data/lib/active_support/message_pack/extensions.rb +292 -0
  126. data/lib/active_support/message_pack/serializer.rb +63 -0
  127. data/lib/active_support/message_pack.rb +50 -0
  128. data/lib/active_support/message_verifier.rb +212 -93
  129. data/lib/active_support/message_verifiers.rb +135 -0
  130. data/lib/active_support/messages/codec.rb +65 -0
  131. data/lib/active_support/messages/metadata.rb +111 -45
  132. data/lib/active_support/messages/rotation_coordinator.rb +93 -0
  133. data/lib/active_support/messages/rotator.rb +34 -32
  134. data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
  135. data/lib/active_support/multibyte/chars.rb +2 -0
  136. data/lib/active_support/multibyte/unicode.rb +9 -37
  137. data/lib/active_support/notifications/fanout.rb +245 -81
  138. data/lib/active_support/notifications/instrumenter.rb +87 -22
  139. data/lib/active_support/notifications.rb +3 -3
  140. data/lib/active_support/number_helper/number_converter.rb +14 -5
  141. data/lib/active_support/number_helper/number_to_currency_converter.rb +6 -6
  142. data/lib/active_support/number_helper/number_to_human_size_converter.rb +3 -3
  143. data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -0
  144. data/lib/active_support/number_helper.rb +379 -317
  145. data/lib/active_support/ordered_hash.rb +3 -3
  146. data/lib/active_support/ordered_options.rb +14 -0
  147. data/lib/active_support/parameter_filter.rb +103 -84
  148. data/lib/active_support/proxy_object.rb +2 -0
  149. data/lib/active_support/railtie.rb +33 -21
  150. data/lib/active_support/reloader.rb +12 -4
  151. data/lib/active_support/rescuable.rb +2 -0
  152. data/lib/active_support/secure_compare_rotator.rb +16 -9
  153. data/lib/active_support/string_inquirer.rb +3 -1
  154. data/lib/active_support/subscriber.rb +9 -27
  155. data/lib/active_support/syntax_error_proxy.rb +60 -0
  156. data/lib/active_support/tagged_logging.rb +64 -24
  157. data/lib/active_support/test_case.rb +153 -6
  158. data/lib/active_support/testing/assertions.rb +26 -10
  159. data/lib/active_support/testing/autorun.rb +0 -2
  160. data/lib/active_support/testing/constant_stubbing.rb +32 -0
  161. data/lib/active_support/testing/deprecation.rb +25 -25
  162. data/lib/active_support/testing/error_reporter_assertions.rb +107 -0
  163. data/lib/active_support/testing/isolation.rb +29 -28
  164. data/lib/active_support/testing/method_call_assertions.rb +21 -8
  165. data/lib/active_support/testing/parallelize_executor.rb +8 -3
  166. data/lib/active_support/testing/setup_and_teardown.rb +2 -0
  167. data/lib/active_support/testing/stream.rb +1 -1
  168. data/lib/active_support/testing/strict_warnings.rb +39 -0
  169. data/lib/active_support/testing/time_helpers.rb +37 -15
  170. data/lib/active_support/time_with_zone.rb +8 -37
  171. data/lib/active_support/values/time_zone.rb +18 -7
  172. data/lib/active_support/version.rb +1 -1
  173. data/lib/active_support/xml_mini/jdom.rb +3 -10
  174. data/lib/active_support/xml_mini/nokogiri.rb +1 -1
  175. data/lib/active_support/xml_mini/nokogirisax.rb +1 -1
  176. data/lib/active_support/xml_mini/rexml.rb +1 -1
  177. data/lib/active_support/xml_mini.rb +2 -2
  178. data/lib/active_support.rb +14 -3
  179. metadata +148 -19
  180. data/lib/active_support/core_ext/array/deprecated_conversions.rb +0 -25
  181. data/lib/active_support/core_ext/date/deprecated_conversions.rb +0 -26
  182. data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +0 -22
  183. data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +0 -60
  184. data/lib/active_support/core_ext/range/deprecated_conversions.rb +0 -26
  185. data/lib/active_support/core_ext/range/include_time_with_zone.rb +0 -7
  186. data/lib/active_support/core_ext/range/overlaps.rb +0 -10
  187. data/lib/active_support/core_ext/time/deprecated_conversions.rb +0 -22
  188. data/lib/active_support/core_ext/uri.rb +0 -5
  189. data/lib/active_support/per_thread_registry.rb +0 -65
@@ -25,45 +25,46 @@ module ActiveSupport
25
25
 
26
26
  module Forking
27
27
  def run_in_isolation(&blk)
28
- read, write = IO.pipe
29
- read.binmode
30
- write.binmode
28
+ IO.pipe do |read, write|
29
+ read.binmode
30
+ write.binmode
31
31
 
32
- pid = fork do
33
- read.close
34
- yield
35
- begin
36
- if error?
37
- failures.map! { |e|
38
- begin
39
- Marshal.dump e
40
- e
41
- rescue TypeError
42
- ex = Exception.new e.message
43
- ex.set_backtrace e.backtrace
44
- Minitest::UnexpectedError.new ex
45
- end
46
- }
32
+ pid = fork do
33
+ read.close
34
+ yield
35
+ begin
36
+ if error?
37
+ failures.map! { |e|
38
+ begin
39
+ Marshal.dump e
40
+ e
41
+ rescue TypeError
42
+ ex = Exception.new e.message
43
+ ex.set_backtrace e.backtrace
44
+ Minitest::UnexpectedError.new ex
45
+ end
46
+ }
47
+ end
48
+ test_result = defined?(Minitest::Result) ? Minitest::Result.from(self) : dup
49
+ result = Marshal.dump(test_result)
47
50
  end
48
- test_result = defined?(Minitest::Result) ? Minitest::Result.from(self) : dup
49
- result = Marshal.dump(test_result)
51
+
52
+ write.puts [result].pack("m")
53
+ exit!
50
54
  end
51
55
 
52
- write.puts [result].pack("m")
53
- exit!
56
+ write.close
57
+ result = read.read
58
+ Process.wait2(pid)
59
+ result.unpack1("m")
54
60
  end
55
-
56
- write.close
57
- result = read.read
58
- Process.wait2(pid)
59
- result.unpack1("m")
60
61
  end
61
62
  end
62
63
 
63
64
  module Subprocess
64
65
  ORIG_ARGV = ARGV.dup unless defined?(ORIG_ARGV)
65
66
 
66
- # Complicated H4X to get this working in windows / jruby with
67
+ # Complicated H4X to get this working in Windows / JRuby with
67
68
  # no forking.
68
69
  def run_in_isolation(&blk)
69
70
  require "tempfile"
@@ -17,24 +17,37 @@ module ActiveSupport
17
17
  assert_equal times, times_called, error
18
18
  end
19
19
 
20
- def assert_called_with(object, method_name, args, returns: nil, &block)
20
+ def assert_called_with(object, method_name, args, returns: false, **kwargs, &block)
21
21
  mock = Minitest::Mock.new
22
-
23
- if args.all?(Array)
24
- args.each { |arg| mock.expect(:call, returns, arg) }
25
- else
26
- mock.expect(:call, returns, args)
27
- end
22
+ expect_called_with(mock, args, returns: returns, **kwargs)
28
23
 
29
24
  object.stub(method_name, mock, &block)
30
25
 
31
- mock.verify
26
+ assert_mock(mock)
32
27
  end
33
28
 
34
29
  def assert_not_called(object, method_name, message = nil, &block)
35
30
  assert_called(object, method_name, message, times: 0, &block)
36
31
  end
37
32
 
33
+ #--
34
+ # This method is a temporary wrapper for mock.expect as part of
35
+ # the Minitest 5.16 / Ruby 3.0 kwargs transition. It can go away
36
+ # when we drop support for Ruby 2.7.
37
+ if Minitest::Mock.instance_method(:expect).parameters.map(&:first).include?(:keyrest)
38
+ def expect_called_with(mock, args, returns: false, **kwargs)
39
+ mock.expect(:call, returns, args, **kwargs)
40
+ end
41
+ else
42
+ def expect_called_with(mock, args, returns: false, **kwargs)
43
+ if !kwargs.empty?
44
+ mock.expect(:call, returns, [*args, kwargs])
45
+ else
46
+ mock.expect(:call, returns, args)
47
+ end
48
+ end
49
+ end
50
+
38
51
  def assert_called_on_instance_of(klass, method_name, message = nil, times: 1, returns: nil)
39
52
  times_called = 0
40
53
  klass.define_method("stubbed_#{method_name}") do |*|
@@ -9,6 +9,7 @@ module ActiveSupport
9
9
  @size = size
10
10
  @parallelize_with = with
11
11
  @threshold = threshold
12
+ @parallelized = false
12
13
  end
13
14
 
14
15
  def start
@@ -49,11 +50,15 @@ module ActiveSupport
49
50
  end
50
51
 
51
52
  def parallelized?
52
- @parallelized if defined?(@parallelized)
53
+ @parallelized
53
54
  end
54
55
 
55
56
  def should_parallelize?
56
- ENV["PARALLEL_WORKERS"] || tests_count > threshold
57
+ (ENV["PARALLEL_WORKERS"] || tests_count > threshold) && many_workers?
58
+ end
59
+
60
+ def many_workers?
61
+ size > 1
57
62
  end
58
63
 
59
64
  def tests_count
@@ -67,7 +72,7 @@ module ActiveSupport
67
72
  def execution_info
68
73
  if parallelized?
69
74
  "Running #{tests_count} tests in parallel using #{parallel_executor.size} #{parallelize_with}"
70
- else
75
+ elsif many_workers?
71
76
  "Running #{tests_count} tests in a single process (parallelization threshold is #{threshold})"
72
77
  end
73
78
  end
@@ -46,6 +46,8 @@ module ActiveSupport
46
46
  run_callbacks :teardown
47
47
  rescue => e
48
48
  self.failures << Minitest::UnexpectedError.new(e)
49
+ rescue Minitest::Assertion => e
50
+ self.failures << e
49
51
  end
50
52
 
51
53
  super
@@ -23,7 +23,7 @@ module ActiveSupport
23
23
  def capture(stream)
24
24
  stream = stream.to_s
25
25
  captured_stream = Tempfile.new(stream)
26
- stream_io = eval("$#{stream}")
26
+ stream_io = eval("$#{stream}", binding, __FILE__, __LINE__)
27
27
  origin_stream = stream_io.dup
28
28
  stream_io.reopen(captured_stream)
29
29
 
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ $VERBOSE = true
4
+ Warning[:deprecated] = true
5
+
6
+ module ActiveSupport
7
+ module RaiseWarnings # :nodoc:
8
+ PROJECT_ROOT = File.expand_path("../../../../", __dir__)
9
+ ALLOWED_WARNINGS = Regexp.union(
10
+ /circular require considered harmful.*delayed_job/, # Bug in delayed job.
11
+
12
+ # Expected non-verbose warning emitted by Rails.
13
+ /Ignoring .*\.yml because it has expired/,
14
+ /Failed to validate the schema cache because/,
15
+ )
16
+
17
+ SUPPRESSED_WARNINGS = Regexp.union(
18
+ # TODO: remove if https://github.com/mikel/mail/pull/1557 or similar fix
19
+ %r{/lib/mail/parsers/.*statement not reached},
20
+ %r{/lib/mail/parsers/.*assigned but unused variable - disp_type_s},
21
+ %r{/lib/mail/parsers/.*assigned but unused variable - testEof}
22
+ )
23
+
24
+ def warn(message, *)
25
+ return if SUPPRESSED_WARNINGS.match?(message)
26
+
27
+ super
28
+
29
+ return unless message.include?(PROJECT_ROOT)
30
+ return if ALLOWED_WARNINGS.match?(message)
31
+ return unless ENV["RAILS_STRICT_WARNINGS"] || ENV["CI"]
32
+
33
+ raise message
34
+ end
35
+ ruby2_keywords :warn if respond_to?(:ruby2_keywords, true)
36
+ end
37
+ end
38
+
39
+ Warning.singleton_class.prepend(ActiveSupport::RaiseWarnings)
@@ -2,7 +2,6 @@
2
2
 
3
3
  require "active_support/core_ext/module/redefine_method"
4
4
  require "active_support/core_ext/time/calculations"
5
- require "concurrent/map"
6
5
 
7
6
  module ActiveSupport
8
7
  module Testing
@@ -11,7 +10,7 @@ module ActiveSupport
11
10
  Stub = Struct.new(:object, :method_name, :original_method)
12
11
 
13
12
  def initialize
14
- @stubs = Concurrent::Map.new { |h, k| h[k] = {} }
13
+ @stubs = Hash.new { |h, k| h[k] = {} }
15
14
  end
16
15
 
17
16
  # Stubs object.method_name with the given block
@@ -26,7 +25,7 @@ module ActiveSupport
26
25
  unstub_object(stub)
27
26
  end
28
27
 
29
- new_name = "__simple_stub__#{method_name}"
28
+ new_name = "__simple_stub__#{method_name}__#{object_id}"
30
29
 
31
30
  @stubs[object.object_id][method_name] = Stub.new(object, method_name, new_name)
32
31
 
@@ -76,6 +75,11 @@ module ActiveSupport
76
75
  # stubbing +Time.now+, +Date.today+, and +DateTime.now+. The stubs are automatically removed
77
76
  # at the end of the test.
78
77
  #
78
+ # Note that the usec for the resulting time will be set to 0 to prevent rounding
79
+ # errors with external services, like MySQL (which will round instead of floor,
80
+ # leading to off-by-one-second errors), unless the <tt>with_usec</tt> argument
81
+ # is set to <tt>true</tt>.
82
+ #
79
83
  # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
80
84
  # travel 1.day
81
85
  # Time.current # => Sun, 10 Nov 2013 15:34:49 EST -05:00
@@ -90,11 +94,11 @@ module ActiveSupport
90
94
  # User.create.created_at # => Sun, 10 Nov 2013 15:34:49 EST -05:00
91
95
  # end
92
96
  # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
93
- def travel(duration, &block)
94
- travel_to Time.now + duration, &block
97
+ def travel(duration, with_usec: false, &block)
98
+ travel_to Time.now + duration, with_usec: with_usec, &block
95
99
  end
96
100
 
97
- # Changes current time to the given time by stubbing +Time.now+,
101
+ # Changes current time to the given time by stubbing +Time.now+, +Time.new+,
98
102
  # +Date.today+, and +DateTime.now+ to return the time or date passed into this method.
99
103
  # The stubs are automatically removed at the end of the test.
100
104
  #
@@ -115,7 +119,8 @@ module ActiveSupport
115
119
  #
116
120
  # Note that the usec for the time passed will be set to 0 to prevent rounding
117
121
  # errors with external services, like MySQL (which will round instead of floor,
118
- # leading to off-by-one-second errors).
122
+ # leading to off-by-one-second errors), unless the <tt>with_usec</tt> argument
123
+ # is set to <tt>true</tt>.
119
124
  #
120
125
  # This method also accepts a block, which will return the current time back to its original
121
126
  # state at the end of the block:
@@ -125,7 +130,7 @@ module ActiveSupport
125
130
  # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
126
131
  # end
127
132
  # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
128
- def travel_to(date_or_time)
133
+ def travel_to(date_or_time, with_usec: false)
129
134
  if block_given? && in_block
130
135
  travel_to_nested_block_call = <<~MSG
131
136
 
@@ -158,14 +163,31 @@ module ActiveSupport
158
163
  now = date_or_time.midnight.to_time
159
164
  elsif date_or_time.is_a?(String)
160
165
  now = Time.zone.parse(date_or_time)
166
+ elsif with_usec
167
+ now = date_or_time.to_time
161
168
  else
162
169
  now = date_or_time.to_time.change(usec: 0)
163
170
  end
164
171
 
165
- stubbed_time = Time.now if simple_stubs.stubbing(Time, :now)
166
- simple_stubs.stub_object(Time, :now) { at(now.to_i) }
167
- simple_stubs.stub_object(Date, :today) { jd(now.to_date.jd) }
168
- simple_stubs.stub_object(DateTime, :now) { jd(now.to_date.jd, now.hour, now.min, now.sec, Rational(now.utc_offset, 86400)) }
172
+ # +now+ must be in local system timezone, because +Time.at(now)+
173
+ # and +now.to_date+ (see stubs below) will use +now+'s timezone too!
174
+ now = now.getlocal
175
+
176
+ stubs = simple_stubs
177
+ stubbed_time = Time.now if stubs.stubbing(Time, :now)
178
+ stubs.stub_object(Time, :now) { at(now) }
179
+
180
+ stubs.stub_object(Time, :new) do |*args, **options|
181
+ if args.empty? && options.empty?
182
+ at(now)
183
+ else
184
+ stub = stubs.stubbing(Time, :new)
185
+ Time.send(stub.original_method, *args, **options)
186
+ end
187
+ end
188
+
189
+ stubs.stub_object(Date, :today) { jd(now.to_date.jd) }
190
+ stubs.stub_object(DateTime, :now) { jd(now.to_date.jd, now.hour, now.min, now.sec, Rational(now.utc_offset, 86400)) }
169
191
 
170
192
  if block_given?
171
193
  begin
@@ -215,7 +237,7 @@ module ActiveSupport
215
237
  end
216
238
  alias_method :unfreeze_time, :travel_back
217
239
 
218
- # Calls +travel_to+ with +Time.now+.
240
+ # Calls +travel_to+ with +Time.now+. Forwards optional <tt>with_usec</tt> argument.
219
241
  #
220
242
  # Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00
221
243
  # freeze_time
@@ -231,8 +253,8 @@ module ActiveSupport
231
253
  # User.create.created_at # => Sun, 09 Jul 2017 15:34:49 EST -05:00
232
254
  # end
233
255
  # Time.current # => Sun, 09 Jul 2017 15:34:50 EST -05:00
234
- def freeze_time(&block)
235
- travel_to Time.now, &block
256
+ def freeze_time(with_usec: false, &block)
257
+ travel_to Time.now, with_usec: with_usec, &block
236
258
  end
237
259
 
238
260
  private
@@ -8,6 +8,8 @@ require "active_support/core_ext/object/acts_like"
8
8
  require "active_support/core_ext/date_and_time/compatibility"
9
9
 
10
10
  module ActiveSupport
11
+ # = Active Support \Time With Zone
12
+ #
11
13
  # A Time-like class that can represent a time in any time zone. Necessary
12
14
  # because standard Ruby Time instances are limited to UTC and the
13
15
  # system's <tt>ENV['TZ']</tt> zone.
@@ -40,18 +42,6 @@ module ActiveSupport
40
42
  # t.is_a?(Time) # => true
41
43
  # t.is_a?(ActiveSupport::TimeWithZone) # => true
42
44
  class TimeWithZone
43
- # Report class name as 'Time' to thwart type checking.
44
- def self.name
45
- ActiveSupport::Deprecation.warn(<<~EOM)
46
- ActiveSupport::TimeWithZone.name has been deprecated and
47
- from Rails 7.1 will use the default Ruby implementation.
48
- You can set `config.active_support.remove_deprecated_time_with_zone_name = true`
49
- to enable the new behavior now.
50
- EOM
51
-
52
- "Time"
53
- end
54
-
55
45
  PRECISIONS = Hash.new { |h, n| h[n] = "%FT%T.%#{n}N" }
56
46
  PRECISIONS[0] = "%FT%T"
57
47
 
@@ -78,7 +68,7 @@ module ActiveSupport
78
68
  alias_method :getutc, :utc
79
69
  alias_method :gmtime, :utc
80
70
 
81
- # Returns the underlying <tt>TZInfo::TimezonePeriod</tt>.
71
+ # Returns the underlying +TZInfo::TimezonePeriod+.
82
72
  def period
83
73
  @period ||= time_zone.period_for_utc(@utc)
84
74
  end
@@ -206,28 +196,9 @@ module ActiveSupport
206
196
  end
207
197
  alias_method :rfc822, :rfc2822
208
198
 
209
- NOT_SET = Object.new # :nodoc:
210
-
211
199
  # Returns a string of the object's date and time.
212
- def to_s(format = NOT_SET)
213
- if format == :db
214
- ActiveSupport::Deprecation.warn(
215
- "TimeWithZone#to_s(:db) is deprecated. Please use TimeWithZone#to_fs(:db) instead."
216
- )
217
- utc.to_fs(format)
218
- elsif formatter = ::Time::DATE_FORMATS[format]
219
- ActiveSupport::Deprecation.warn(
220
- "TimeWithZone#to_s(#{format.inspect}) is deprecated. Please use TimeWithZone#to_fs(#{format.inspect}) instead."
221
- )
222
- formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
223
- elsif format == NOT_SET
224
- "#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}" # mimicking Ruby Time#to_s format
225
- else
226
- ActiveSupport::Deprecation.warn(
227
- "TimeWithZone#to_s(#{format.inspect}) is deprecated. Please use TimeWithZone#to_fs(#{format.inspect}) instead."
228
- )
229
- "#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}" # mimicking Ruby Time#to_s format
230
- end
200
+ def to_s
201
+ "#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}" # mimicking Ruby Time#to_s format
231
202
  end
232
203
 
233
204
  # Returns a string of the object's date and time.
@@ -237,7 +208,7 @@ module ActiveSupport
237
208
  # Accepts an optional <tt>format</tt>:
238
209
  # * <tt>:default</tt> - default value, mimics Ruby Time#to_s format.
239
210
  # * <tt>:db</tt> - format outputs time in UTC :db time. See Time#to_fs(:db).
240
- # * Any key in <tt>Time::DATE_FORMATS</tt> can be used. See active_support/core_ext/time/conversions.rb.
211
+ # * Any key in +Time::DATE_FORMATS+ can be used. See active_support/core_ext/time/conversions.rb.
241
212
  def to_fs(format = :default)
242
213
  if format == :db
243
214
  utc.to_fs(format)
@@ -566,8 +537,8 @@ module ActiveSupport
566
537
 
567
538
  # Send the missing method to +time+ instance, and wrap result in a new
568
539
  # TimeWithZone with the existing +time_zone+.
569
- def method_missing(sym, *args, &block)
570
- wrap_with_time_zone time.__send__(sym, *args, &block)
540
+ def method_missing(...)
541
+ wrap_with_time_zone time.__send__(...)
571
542
  rescue NoMethodError => e
572
543
  raise e, e.message.sub(time.inspect, inspect).sub("Time", "ActiveSupport::TimeWithZone"), e.backtrace
573
544
  end
@@ -4,18 +4,20 @@ require "tzinfo"
4
4
  require "concurrent/map"
5
5
 
6
6
  module ActiveSupport
7
- # The TimeZone class serves as a wrapper around <tt>TZInfo::Timezone</tt> instances.
7
+ # = Active Support \Time Zone
8
+ #
9
+ # The TimeZone class serves as a wrapper around +TZInfo::Timezone+ instances.
8
10
  # It allows us to do the following:
9
11
  #
10
12
  # * Limit the set of zones provided by TZInfo to a meaningful subset of 134
11
13
  # zones.
12
14
  # * Retrieve and display zones with a friendlier name
13
15
  # (e.g., "Eastern Time (US & Canada)" instead of "America/New_York").
14
- # * Lazily load <tt>TZInfo::Timezone</tt> instances only when they're needed.
16
+ # * Lazily load +TZInfo::Timezone+ instances only when they're needed.
15
17
  # * Create ActiveSupport::TimeWithZone instances via TimeZone's +local+,
16
18
  # +parse+, +at+, and +now+ methods.
17
19
  #
18
- # If you set <tt>config.time_zone</tt> in the Rails Application, you can
20
+ # If you set <tt>config.time_zone</tt> in the \Rails Application, you can
19
21
  # access this TimeZone object via <tt>Time.zone</tt>:
20
22
  #
21
23
  # # application.rb:
@@ -27,7 +29,7 @@ module ActiveSupport
27
29
  # Time.zone.name # => "Eastern Time (US & Canada)"
28
30
  # Time.zone.now # => Sun, 18 May 2008 14:30:44 EDT -04:00
29
31
  class TimeZone
30
- # Keys are Rails TimeZone names, values are TZInfo identifiers.
32
+ # Keys are \Rails TimeZone names, values are TZInfo identifiers.
31
33
  MAPPING = {
32
34
  "International Date Line West" => "Etc/GMT+12",
33
35
  "Midway Island" => "Pacific/Midway",
@@ -159,7 +161,7 @@ module ActiveSupport
159
161
  "Yakutsk" => "Asia/Yakutsk",
160
162
  "Darwin" => "Australia/Darwin",
161
163
  "Adelaide" => "Australia/Adelaide",
162
- "Canberra" => "Australia/Melbourne",
164
+ "Canberra" => "Australia/Canberra",
163
165
  "Melbourne" => "Australia/Melbourne",
164
166
  "Sydney" => "Australia/Sydney",
165
167
  "Brisbane" => "Australia/Brisbane",
@@ -206,7 +208,9 @@ module ActiveSupport
206
208
  TZInfo::Timezone.get(MAPPING[name] || name)
207
209
  end
208
210
 
211
+ # :stopdoc:
209
212
  alias_method :create, :new
213
+ # :startdoc:
210
214
 
211
215
  # Returns a TimeZone instance with the given name, or +nil+ if no
212
216
  # such TimeZone instance exists. (This exists to support the use of
@@ -294,15 +298,22 @@ module ActiveSupport
294
298
  attr_reader :name
295
299
  attr_reader :tzinfo
296
300
 
301
+ ##
302
+ # :singleton-method: create
303
+ # :call-seq: create(name, utc_offset = nil, tzinfo = nil)
304
+ #
297
305
  # Create a new TimeZone object with the given name and offset. The
298
306
  # offset is the number of seconds that this time zone is offset from UTC
299
307
  # (GMT). Seconds were chosen as the offset unit because that is the unit
300
308
  # that Ruby uses to represent time zone offsets (see Time#utc_offset).
309
+
310
+ # :stopdoc:
301
311
  def initialize(name, utc_offset = nil, tzinfo = nil)
302
312
  @name = name
303
313
  @utc_offset = utc_offset
304
314
  @tzinfo = tzinfo || TimeZone.find_tzinfo(name)
305
315
  end
316
+ # :startdoc:
306
317
 
307
318
  # Returns the offset of this time zone from UTC in seconds.
308
319
  def utc_offset
@@ -543,13 +554,13 @@ module ActiveSupport
543
554
  tzinfo.local_to_utc(time, dst)
544
555
  end
545
556
 
546
- # Available so that TimeZone instances respond like <tt>TZInfo::Timezone</tt>
557
+ # Available so that TimeZone instances respond like +TZInfo::Timezone+
547
558
  # instances.
548
559
  def period_for_utc(time)
549
560
  tzinfo.period_for_utc(time)
550
561
  end
551
562
 
552
- # Available so that TimeZone instances respond like <tt>TZInfo::Timezone</tt>
563
+ # Available so that TimeZone instances respond like +TZInfo::Timezone+
553
564
  # instances.
554
565
  def period_for_local(time, dst = true)
555
566
  tzinfo.period_for_local(time, dst) { |periods| periods.last }
@@ -3,7 +3,7 @@
3
3
  require_relative "gem_version"
4
4
 
5
5
  module ActiveSupport
6
- # Returns the currently loaded version of Active Support as a <tt>Gem::Version</tt>.
6
+ # Returns the currently loaded version of Active Support as a +Gem::Version+.
7
7
  def self.version
8
8
  gem_version
9
9
  end
@@ -20,13 +20,6 @@ module ActiveSupport
20
20
 
21
21
  CONTENT_KEY = "__content__"
22
22
 
23
- NODE_TYPE_NAMES = %w{ATTRIBUTE_NODE CDATA_SECTION_NODE COMMENT_NODE DOCUMENT_FRAGMENT_NODE
24
- DOCUMENT_NODE DOCUMENT_TYPE_NODE ELEMENT_NODE ENTITY_NODE ENTITY_REFERENCE_NODE NOTATION_NODE
25
- PROCESSING_INSTRUCTION_NODE TEXT_NODE}
26
-
27
- node_type_map = {}
28
- NODE_TYPE_NAMES.each { |type| node_type_map[Node.send(type)] = type }
29
-
30
23
  # Parse an XML Document string or IO into a simple hash using Java's jdom.
31
24
  # data::
32
25
  # XML Document string or IO to parse
@@ -80,7 +73,7 @@ module ActiveSupport
80
73
  if child_nodes.length > 0
81
74
  (0...child_nodes.length).each do |i|
82
75
  child = child_nodes.item(i)
83
- merge_element!(hash, child, depth - 1) unless child.node_type == Node.TEXT_NODE
76
+ merge_element!(hash, child, depth - 1) unless child.node_type == Node::TEXT_NODE
84
77
  end
85
78
  merge_texts!(hash, element) unless empty_content?(element)
86
79
  hash
@@ -156,7 +149,7 @@ module ActiveSupport
156
149
  child_nodes = element.child_nodes
157
150
  (0...child_nodes.length).each do |i|
158
151
  item = child_nodes.item(i)
159
- if item.node_type == Node.TEXT_NODE
152
+ if item.node_type == Node::TEXT_NODE
160
153
  texts << item.get_data
161
154
  end
162
155
  end
@@ -172,7 +165,7 @@ module ActiveSupport
172
165
  child_nodes = element.child_nodes
173
166
  (0...child_nodes.length).each do |i|
174
167
  item = child_nodes.item(i)
175
- if item.node_type == Node.TEXT_NODE
168
+ if item.node_type == Node::TEXT_NODE
176
169
  text << item.get_data.strip
177
170
  end
178
171
  end
@@ -3,7 +3,7 @@
3
3
  begin
4
4
  require "nokogiri"
5
5
  rescue LoadError => e
6
- $stderr.puts "You don't have nokogiri installed in your application. Please add it to your Gemfile and run bundle install"
6
+ warn "You don't have nokogiri installed in your application. Please add it to your Gemfile and run bundle install"
7
7
  raise e
8
8
  end
9
9
  require "active_support/core_ext/object/blank"
@@ -3,7 +3,7 @@
3
3
  begin
4
4
  require "nokogiri"
5
5
  rescue LoadError => e
6
- $stderr.puts "You don't have nokogiri installed in your application. Please add it to your Gemfile and run bundle install"
6
+ warn "You don't have nokogiri installed in your application. Please add it to your Gemfile and run bundle install"
7
7
  raise e
8
8
  end
9
9
  require "active_support/core_ext/object/blank"
@@ -41,7 +41,7 @@ module ActiveSupport
41
41
  def require_rexml
42
42
  silence_warnings { require "rexml/document" }
43
43
  rescue LoadError => e
44
- $stderr.puts "You don't have rexml installed in your application. Please add it to your Gemfile and run bundle install"
44
+ warn "You don't have rexml installed in your application. Please add it to your Gemfile and run bundle install"
45
45
  raise e
46
46
  end
47
47
 
@@ -9,10 +9,10 @@ require "active_support/core_ext/string/inflections"
9
9
  require "active_support/core_ext/date_time/calculations"
10
10
 
11
11
  module ActiveSupport
12
- # = XmlMini
12
+ # = \XmlMini
13
13
  #
14
14
  # To use the much faster libxml parser:
15
- # gem 'libxml-ruby', '=0.9.7'
15
+ # gem 'libxml-ruby'
16
16
  # XmlMini.backend = 'LibXML'
17
17
  module XmlMini
18
18
  extend self