activesupport 5.2.4.3 → 7.0.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 (228) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +244 -459
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -3
  5. data/lib/active_support/actionable_error.rb +48 -0
  6. data/lib/active_support/array_inquirer.rb +2 -2
  7. data/lib/active_support/backtrace_cleaner.rb +31 -5
  8. data/lib/active_support/benchmarkable.rb +3 -3
  9. data/lib/active_support/cache/file_store.rb +47 -41
  10. data/lib/active_support/cache/mem_cache_store.rb +151 -40
  11. data/lib/active_support/cache/memory_store.rb +68 -34
  12. data/lib/active_support/cache/null_store.rb +16 -3
  13. data/lib/active_support/cache/redis_cache_store.rb +103 -101
  14. data/lib/active_support/cache/strategy/local_cache.rb +56 -64
  15. data/lib/active_support/cache.rb +333 -116
  16. data/lib/active_support/callbacks.rb +244 -128
  17. data/lib/active_support/code_generator.rb +65 -0
  18. data/lib/active_support/concern.rb +72 -5
  19. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +16 -0
  20. data/lib/active_support/concurrency/share_lock.rb +2 -3
  21. data/lib/active_support/configurable.rb +15 -16
  22. data/lib/active_support/configuration_file.rb +51 -0
  23. data/lib/active_support/core_ext/array/access.rb +15 -7
  24. data/lib/active_support/core_ext/array/conversions.rb +18 -17
  25. data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
  26. data/lib/active_support/core_ext/array/extract.rb +21 -0
  27. data/lib/active_support/core_ext/array/grouping.rb +6 -6
  28. data/lib/active_support/core_ext/array/inquiry.rb +2 -2
  29. data/lib/active_support/core_ext/array.rb +2 -1
  30. data/lib/active_support/core_ext/benchmark.rb +2 -2
  31. data/lib/active_support/core_ext/big_decimal/conversions.rb +1 -1
  32. data/lib/active_support/core_ext/class/attribute.rb +32 -47
  33. data/lib/active_support/core_ext/class/subclasses.rb +9 -22
  34. data/lib/active_support/core_ext/date/blank.rb +1 -1
  35. data/lib/active_support/core_ext/date/calculations.rb +15 -14
  36. data/lib/active_support/core_ext/date/conversions.rb +16 -15
  37. data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
  38. data/lib/active_support/core_ext/date.rb +1 -0
  39. data/lib/active_support/core_ext/date_and_time/calculations.rb +41 -51
  40. data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
  41. data/lib/active_support/core_ext/date_and_time/zones.rb +0 -1
  42. data/lib/active_support/core_ext/date_time/blank.rb +1 -1
  43. data/lib/active_support/core_ext/date_time/calculations.rb +1 -1
  44. data/lib/active_support/core_ext/date_time/conversions.rb +13 -14
  45. data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
  46. data/lib/active_support/core_ext/date_time.rb +1 -0
  47. data/lib/active_support/core_ext/digest/uuid.rb +39 -13
  48. data/lib/active_support/core_ext/enumerable.rb +241 -76
  49. data/lib/active_support/core_ext/file/atomic.rb +3 -1
  50. data/lib/active_support/core_ext/hash/conversions.rb +3 -4
  51. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  52. data/lib/active_support/core_ext/hash/except.rb +2 -2
  53. data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
  54. data/lib/active_support/core_ext/hash/keys.rb +2 -31
  55. data/lib/active_support/core_ext/hash/slice.rb +6 -27
  56. data/lib/active_support/core_ext/hash.rb +1 -2
  57. data/lib/active_support/core_ext/integer/multiple.rb +1 -1
  58. data/lib/active_support/core_ext/kernel/reporting.rb +4 -4
  59. data/lib/active_support/core_ext/kernel/singleton_class.rb +1 -1
  60. data/lib/active_support/core_ext/kernel.rb +0 -1
  61. data/lib/active_support/core_ext/load_error.rb +1 -1
  62. data/lib/active_support/core_ext/module/attr_internal.rb +2 -2
  63. data/lib/active_support/core_ext/module/attribute_accessors.rb +32 -39
  64. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +35 -28
  65. data/lib/active_support/core_ext/module/concerning.rb +8 -2
  66. data/lib/active_support/core_ext/module/delegation.rb +70 -33
  67. data/lib/active_support/core_ext/module/introspection.rb +16 -15
  68. data/lib/active_support/core_ext/module/redefine_method.rb +8 -17
  69. data/lib/active_support/core_ext/module.rb +0 -1
  70. data/lib/active_support/core_ext/name_error.rb +23 -2
  71. data/lib/active_support/core_ext/numeric/conversions.rb +132 -129
  72. data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
  73. data/lib/active_support/core_ext/numeric.rb +1 -1
  74. data/lib/active_support/core_ext/object/acts_like.rb +29 -5
  75. data/lib/active_support/core_ext/object/blank.rb +3 -4
  76. data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
  77. data/lib/active_support/core_ext/object/duplicable.rb +14 -110
  78. data/lib/active_support/core_ext/object/json.rb +44 -27
  79. data/lib/active_support/core_ext/object/to_query.rb +2 -2
  80. data/lib/active_support/core_ext/object/try.rb +24 -14
  81. data/lib/active_support/core_ext/object/with_options.rb +21 -2
  82. data/lib/active_support/core_ext/pathname/existence.rb +21 -0
  83. data/lib/active_support/core_ext/pathname.rb +3 -0
  84. data/lib/active_support/core_ext/range/compare_range.rb +23 -27
  85. data/lib/active_support/core_ext/range/conversions.rb +32 -30
  86. data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
  87. data/lib/active_support/core_ext/range/each.rb +1 -2
  88. data/lib/active_support/core_ext/range/include_time_with_zone.rb +4 -20
  89. data/lib/active_support/core_ext/range/overlaps.rb +1 -1
  90. data/lib/active_support/core_ext/range.rb +1 -1
  91. data/lib/active_support/core_ext/regexp.rb +8 -5
  92. data/lib/active_support/core_ext/securerandom.rb +23 -3
  93. data/lib/active_support/core_ext/string/access.rb +5 -16
  94. data/lib/active_support/core_ext/string/conversions.rb +3 -2
  95. data/lib/active_support/core_ext/string/filters.rb +42 -1
  96. data/lib/active_support/core_ext/string/inflections.rb +46 -7
  97. data/lib/active_support/core_ext/string/inquiry.rb +2 -1
  98. data/lib/active_support/core_ext/string/multibyte.rb +6 -5
  99. data/lib/active_support/core_ext/string/output_safety.rb +129 -20
  100. data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -2
  101. data/lib/active_support/core_ext/string/strip.rb +3 -1
  102. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
  103. data/lib/active_support/core_ext/symbol.rb +3 -0
  104. data/lib/active_support/core_ext/time/calculations.rb +59 -10
  105. data/lib/active_support/core_ext/time/conversions.rb +15 -12
  106. data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
  107. data/lib/active_support/core_ext/time/zones.rb +7 -22
  108. data/lib/active_support/core_ext/time.rb +1 -0
  109. data/lib/active_support/core_ext/uri.rb +3 -22
  110. data/lib/active_support/core_ext.rb +2 -1
  111. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  112. data/lib/active_support/current_attributes.rb +47 -16
  113. data/lib/active_support/dependencies/interlock.rb +10 -18
  114. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  115. data/lib/active_support/dependencies.rb +60 -715
  116. data/lib/active_support/deprecation/behaviors.rb +21 -5
  117. data/lib/active_support/deprecation/disallowed.rb +56 -0
  118. data/lib/active_support/deprecation/instance_delegator.rb +0 -1
  119. data/lib/active_support/deprecation/method_wrappers.rb +18 -23
  120. data/lib/active_support/deprecation/proxy_wrappers.rb +31 -8
  121. data/lib/active_support/deprecation/reporting.rb +50 -7
  122. data/lib/active_support/deprecation.rb +7 -2
  123. data/lib/active_support/descendants_tracker.rb +190 -34
  124. data/lib/active_support/digest.rb +5 -3
  125. data/lib/active_support/duration/iso8601_parser.rb +5 -7
  126. data/lib/active_support/duration/iso8601_serializer.rb +27 -15
  127. data/lib/active_support/duration.rb +149 -67
  128. data/lib/active_support/encrypted_configuration.rb +12 -5
  129. data/lib/active_support/encrypted_file.rb +23 -5
  130. data/lib/active_support/environment_inquirer.rb +20 -0
  131. data/lib/active_support/error_reporter.rb +117 -0
  132. data/lib/active_support/evented_file_update_checker.rb +85 -122
  133. data/lib/active_support/execution_context/test_helper.rb +13 -0
  134. data/lib/active_support/execution_context.rb +53 -0
  135. data/lib/active_support/execution_wrapper.rb +44 -21
  136. data/lib/active_support/executor/test_helper.rb +7 -0
  137. data/lib/active_support/file_update_checker.rb +0 -1
  138. data/lib/active_support/fork_tracker.rb +71 -0
  139. data/lib/active_support/gem_version.rb +5 -5
  140. data/lib/active_support/hash_with_indifferent_access.rb +73 -43
  141. data/lib/active_support/html_safe_translation.rb +43 -0
  142. data/lib/active_support/i18n.rb +2 -0
  143. data/lib/active_support/i18n_railtie.rb +15 -8
  144. data/lib/active_support/inflector/inflections.rb +25 -14
  145. data/lib/active_support/inflector/methods.rb +38 -71
  146. data/lib/active_support/inflector/transliterate.rb +47 -18
  147. data/lib/active_support/isolated_execution_state.rb +72 -0
  148. data/lib/active_support/json/decoding.rb +25 -26
  149. data/lib/active_support/json/encoding.rb +14 -6
  150. data/lib/active_support/key_generator.rb +23 -38
  151. data/lib/active_support/lazy_load_hooks.rb +19 -5
  152. data/lib/active_support/locale/en.rb +33 -0
  153. data/lib/active_support/locale/en.yml +8 -4
  154. data/lib/active_support/log_subscriber/test_helper.rb +2 -2
  155. data/lib/active_support/log_subscriber.rb +51 -11
  156. data/lib/active_support/logger.rb +6 -22
  157. data/lib/active_support/logger_silence.rb +11 -19
  158. data/lib/active_support/logger_thread_safe_level.rb +45 -10
  159. data/lib/active_support/message_encryptor.rb +20 -19
  160. data/lib/active_support/message_verifier.rb +53 -21
  161. data/lib/active_support/messages/metadata.rb +13 -4
  162. data/lib/active_support/messages/rotation_configuration.rb +2 -1
  163. data/lib/active_support/messages/rotator.rb +10 -9
  164. data/lib/active_support/multibyte/chars.rb +17 -76
  165. data/lib/active_support/multibyte/unicode.rb +7 -331
  166. data/lib/active_support/multibyte.rb +1 -1
  167. data/lib/active_support/notifications/fanout.rb +163 -37
  168. data/lib/active_support/notifications/instrumenter.rb +90 -11
  169. data/lib/active_support/notifications.rb +88 -30
  170. data/lib/active_support/number_helper/number_converter.rb +6 -9
  171. data/lib/active_support/number_helper/number_to_currency_converter.rb +12 -12
  172. data/lib/active_support/number_helper/number_to_delimited_converter.rb +4 -3
  173. data/lib/active_support/number_helper/number_to_human_converter.rb +4 -3
  174. data/lib/active_support/number_helper/number_to_human_size_converter.rb +5 -4
  175. data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
  176. data/lib/active_support/number_helper/number_to_phone_converter.rb +3 -2
  177. data/lib/active_support/number_helper/number_to_rounded_converter.rb +12 -7
  178. data/lib/active_support/number_helper/rounding_helper.rb +12 -32
  179. data/lib/active_support/number_helper.rb +36 -12
  180. data/lib/active_support/option_merger.rb +15 -4
  181. data/lib/active_support/ordered_hash.rb +2 -2
  182. data/lib/active_support/ordered_options.rb +14 -4
  183. data/lib/active_support/parameter_filter.rb +138 -0
  184. data/lib/active_support/per_thread_registry.rb +6 -1
  185. data/lib/active_support/rails.rb +1 -10
  186. data/lib/active_support/railtie.rb +77 -5
  187. data/lib/active_support/reloader.rb +5 -6
  188. data/lib/active_support/rescuable.rb +8 -8
  189. data/lib/active_support/ruby_features.rb +7 -0
  190. data/lib/active_support/secure_compare_rotator.rb +51 -0
  191. data/lib/active_support/security_utils.rb +19 -12
  192. data/lib/active_support/string_inquirer.rb +2 -3
  193. data/lib/active_support/subscriber.rb +79 -46
  194. data/lib/active_support/tagged_logging.rb +58 -9
  195. data/lib/active_support/test_case.rb +79 -0
  196. data/lib/active_support/testing/assertions.rb +62 -11
  197. data/lib/active_support/testing/deprecation.rb +52 -2
  198. data/lib/active_support/testing/file_fixtures.rb +2 -0
  199. data/lib/active_support/testing/isolation.rb +4 -4
  200. data/lib/active_support/testing/method_call_assertions.rb +32 -5
  201. data/lib/active_support/testing/parallelization/server.rb +82 -0
  202. data/lib/active_support/testing/parallelization/worker.rb +103 -0
  203. data/lib/active_support/testing/parallelization.rb +55 -0
  204. data/lib/active_support/testing/parallelize_executor.rb +76 -0
  205. data/lib/active_support/testing/stream.rb +4 -7
  206. data/lib/active_support/testing/tagged_logging.rb +1 -1
  207. data/lib/active_support/testing/time_helpers.rb +60 -14
  208. data/lib/active_support/time_with_zone.rb +139 -64
  209. data/lib/active_support/values/time_zone.rb +66 -30
  210. data/lib/active_support/version.rb +1 -1
  211. data/lib/active_support/xml_mini/jdom.rb +3 -4
  212. data/lib/active_support/xml_mini/libxml.rb +7 -7
  213. data/lib/active_support/xml_mini/libxmlsax.rb +5 -5
  214. data/lib/active_support/xml_mini/nokogiri.rb +6 -6
  215. data/lib/active_support/xml_mini/nokogirisax.rb +4 -4
  216. data/lib/active_support/xml_mini/rexml.rb +11 -4
  217. data/lib/active_support/xml_mini.rb +7 -14
  218. data/lib/active_support.rb +30 -1
  219. metadata +64 -35
  220. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -9
  221. data/lib/active_support/core_ext/hash/compact.rb +0 -29
  222. data/lib/active_support/core_ext/hash/transform_values.rb +0 -32
  223. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -13
  224. data/lib/active_support/core_ext/marshal.rb +0 -24
  225. data/lib/active_support/core_ext/module/reachable.rb +0 -11
  226. data/lib/active_support/core_ext/numeric/inquiry.rb +0 -28
  227. data/lib/active_support/core_ext/range/include_range.rb +0 -3
  228. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ module Testing
5
+ class ParallelizeExecutor # :nodoc:
6
+ attr_reader :size, :parallelize_with, :threshold
7
+
8
+ def initialize(size:, with:, threshold: ActiveSupport.test_parallelization_threshold)
9
+ @size = size
10
+ @parallelize_with = with
11
+ @threshold = threshold
12
+ end
13
+
14
+ def start
15
+ parallelize if should_parallelize?
16
+ show_execution_info
17
+
18
+ parallel_executor.start if parallelized?
19
+ end
20
+
21
+ def <<(work)
22
+ parallel_executor << work if parallelized?
23
+ end
24
+
25
+ def shutdown
26
+ parallel_executor.shutdown if parallelized?
27
+ end
28
+
29
+ private
30
+ def parallel_executor
31
+ @parallel_executor ||= build_parallel_executor
32
+ end
33
+
34
+ def build_parallel_executor
35
+ case parallelize_with
36
+ when :processes
37
+ Testing::Parallelization.new(size)
38
+ when :threads
39
+ ActiveSupport::TestCase.lock_threads = false if defined?(ActiveSupport::TestCase.lock_threads)
40
+ Minitest::Parallel::Executor.new(size)
41
+ else
42
+ raise ArgumentError, "#{parallelize_with} is not a supported parallelization executor."
43
+ end
44
+ end
45
+
46
+ def parallelize
47
+ @parallelized = true
48
+ Minitest::Test.parallelize_me!
49
+ end
50
+
51
+ def parallelized?
52
+ @parallelized if defined?(@parallelized)
53
+ end
54
+
55
+ def should_parallelize?
56
+ ENV["PARALLEL_WORKERS"] || tests_count > threshold
57
+ end
58
+
59
+ def tests_count
60
+ @tests_count ||= Minitest::Runnable.runnables.sum { |runnable| runnable.runnable_methods.size }
61
+ end
62
+
63
+ def show_execution_info
64
+ puts execution_info
65
+ end
66
+
67
+ def execution_info
68
+ if parallelized?
69
+ "Running #{tests_count} tests in parallel using #{parallel_executor.size} #{parallelize_with}"
70
+ else
71
+ "Running #{tests_count} tests in a single process (parallelization threshold is #{threshold})"
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -2,9 +2,8 @@
2
2
 
3
3
  module ActiveSupport
4
4
  module Testing
5
- module Stream #:nodoc:
5
+ module Stream # :nodoc:
6
6
  private
7
-
8
7
  def silence_stream(stream)
9
8
  old_stream = stream.dup
10
9
  stream.reopen(IO::NULL)
@@ -15,11 +14,9 @@ module ActiveSupport
15
14
  old_stream.close
16
15
  end
17
16
 
18
- def quietly
17
+ def quietly(&block)
19
18
  silence_stream(STDOUT) do
20
- silence_stream(STDERR) do
21
- yield
22
- end
19
+ silence_stream(STDERR, &block)
23
20
  end
24
21
  end
25
22
 
@@ -33,7 +30,7 @@ module ActiveSupport
33
30
  yield
34
31
 
35
32
  stream_io.rewind
36
- return captured_stream.read
33
+ captured_stream.read
37
34
  ensure
38
35
  captured_stream.close
39
36
  captured_stream.unlink
@@ -4,7 +4,7 @@ module ActiveSupport
4
4
  module Testing
5
5
  # Logs a "PostsControllerTest: test name" heading before each test to
6
6
  # make test.log easier to search and follow along with.
7
- module TaggedLogging #:nodoc:
7
+ module TaggedLogging # :nodoc:
8
8
  attr_writer :tagged_logger
9
9
 
10
10
  def before_setup
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_support/core_ext/module/redefine_method"
4
- require "active_support/core_ext/string/strip" # for strip_heredoc
5
4
  require "active_support/core_ext/time/calculations"
6
5
  require "concurrent/map"
7
6
 
8
7
  module ActiveSupport
9
8
  module Testing
9
+ # Manages stubs for TimeHelpers
10
10
  class SimpleStubs # :nodoc:
11
11
  Stub = Struct.new(:object, :method_name, :original_method)
12
12
 
@@ -14,6 +14,13 @@ module ActiveSupport
14
14
  @stubs = Concurrent::Map.new { |h, k| h[k] = {} }
15
15
  end
16
16
 
17
+ # Stubs object.method_name with the given block
18
+ # If the method is already stubbed, remove that stub
19
+ # so that removing this stub will restore the original implementation.
20
+ # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
21
+ # target = Time.zone.local(2004, 11, 24, 1, 4, 44)
22
+ # simple_stubs.stub_object(Time, :now) { at(target.to_i) }
23
+ # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
17
24
  def stub_object(object, method_name, &block)
18
25
  if stub = stubbing(object, method_name)
19
26
  unstub_object(stub)
@@ -23,10 +30,11 @@ module ActiveSupport
23
30
 
24
31
  @stubs[object.object_id][method_name] = Stub.new(object, method_name, new_name)
25
32
 
26
- object.singleton_class.send :alias_method, new_name, method_name
33
+ object.singleton_class.alias_method new_name, method_name
27
34
  object.define_singleton_method(method_name, &block)
28
35
  end
29
36
 
37
+ # Remove all object-method stubs held by this instance
30
38
  def unstub_all!
31
39
  @stubs.each_value do |object_stubs|
32
40
  object_stubs.each_value do |stub|
@@ -36,17 +44,24 @@ module ActiveSupport
36
44
  @stubs.clear
37
45
  end
38
46
 
47
+ # Returns the Stub for object#method_name
48
+ # (nil if it is not stubbed)
39
49
  def stubbing(object, method_name)
40
50
  @stubs[object.object_id][method_name]
41
51
  end
42
52
 
43
- private
53
+ # Returns true if any stubs are set, false if there are none
54
+ def stubbed?
55
+ !@stubs.empty?
56
+ end
44
57
 
58
+ private
59
+ # Restores the original object.method described by the Stub
45
60
  def unstub_object(stub)
46
61
  singleton_class = stub.object.singleton_class
47
- singleton_class.send :silence_redefinition_of_method, stub.method_name
48
- singleton_class.send :alias_method, stub.method_name, stub.original_method
49
- singleton_class.send :undef_method, stub.original_method
62
+ singleton_class.silence_redefinition_of_method stub.method_name
63
+ singleton_class.alias_method stub.method_name, stub.original_method
64
+ singleton_class.undef_method stub.original_method
50
65
  end
51
66
  end
52
67
 
@@ -84,7 +99,7 @@ module ActiveSupport
84
99
  # The stubs are automatically removed at the end of the test.
85
100
  #
86
101
  # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
87
- # travel_to Time.zone.local(2004, 11, 24, 01, 04, 44)
102
+ # travel_to Time.zone.local(2004, 11, 24, 1, 4, 44)
88
103
  # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
89
104
  # Date.current # => Wed, 24 Nov 2004
90
105
  # DateTime.current # => Wed, 24 Nov 2004 01:04:44 -0500
@@ -106,13 +121,13 @@ module ActiveSupport
106
121
  # state at the end of the block:
107
122
  #
108
123
  # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
109
- # travel_to Time.zone.local(2004, 11, 24, 01, 04, 44) do
124
+ # travel_to Time.zone.local(2004, 11, 24, 1, 4, 44) do
110
125
  # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
111
126
  # end
112
127
  # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
113
128
  def travel_to(date_or_time)
114
- if block_given? && simple_stubs.stubbing(Time, :now)
115
- travel_to_nested_block_call = <<-MSG.strip_heredoc
129
+ if block_given? && in_block
130
+ travel_to_nested_block_call = <<~MSG
116
131
 
117
132
  Calling `travel_to` with a block, when we have previously already made a call to `travel_to`, can lead to confusing time stubbing.
118
133
 
@@ -141,34 +156,64 @@ module ActiveSupport
141
156
 
142
157
  if date_or_time.is_a?(Date) && !date_or_time.is_a?(DateTime)
143
158
  now = date_or_time.midnight.to_time
159
+ elsif date_or_time.is_a?(String)
160
+ now = Time.zone.parse(date_or_time)
144
161
  else
145
162
  now = date_or_time.to_time.change(usec: 0)
146
163
  end
147
164
 
165
+ stubbed_time = Time.now if simple_stubs.stubbing(Time, :now)
148
166
  simple_stubs.stub_object(Time, :now) { at(now.to_i) }
149
167
  simple_stubs.stub_object(Date, :today) { jd(now.to_date.jd) }
150
168
  simple_stubs.stub_object(DateTime, :now) { jd(now.to_date.jd, now.hour, now.min, now.sec, Rational(now.utc_offset, 86400)) }
151
169
 
152
170
  if block_given?
153
171
  begin
172
+ self.in_block = true
154
173
  yield
155
174
  ensure
156
- travel_back
175
+ if stubbed_time
176
+ travel_to stubbed_time
177
+ else
178
+ travel_back
179
+ end
180
+ self.in_block = false
157
181
  end
158
182
  end
159
183
  end
160
184
 
161
185
  # Returns the current time back to its original state, by removing the stubs added by
162
- # +travel+ and +travel_to+.
186
+ # +travel+, +travel_to+, and +freeze_time+.
163
187
  #
164
188
  # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
165
- # travel_to Time.zone.local(2004, 11, 24, 01, 04, 44)
189
+ #
190
+ # travel_to Time.zone.local(2004, 11, 24, 1, 4, 44)
166
191
  # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
192
+ #
167
193
  # travel_back
168
194
  # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
195
+ #
196
+ # This method also accepts a block, which brings the stubs back at the end of the block:
197
+ #
198
+ # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
199
+ #
200
+ # travel_to Time.zone.local(2004, 11, 24, 1, 4, 44)
201
+ # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
202
+ #
203
+ # travel_back do
204
+ # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
205
+ # end
206
+ #
207
+ # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
169
208
  def travel_back
209
+ stubbed_time = Time.current if block_given? && simple_stubs.stubbed?
210
+
170
211
  simple_stubs.unstub_all!
212
+ yield if block_given?
213
+ ensure
214
+ travel_to stubbed_time if stubbed_time
171
215
  end
216
+ alias_method :unfreeze_time, :travel_back
172
217
 
173
218
  # Calls +travel_to+ with +Time.now+.
174
219
  #
@@ -191,10 +236,11 @@ module ActiveSupport
191
236
  end
192
237
 
193
238
  private
194
-
195
239
  def simple_stubs
196
240
  @simple_stubs ||= SimpleStubs.new
197
241
  end
242
+
243
+ attr_accessor :in_block
198
244
  end
199
245
  end
200
246
  end