activesupport 1.2.4 → 8.1.2

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 (309) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +505 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +40 -0
  5. data/lib/active_support/actionable_error.rb +50 -0
  6. data/lib/active_support/all.rb +5 -0
  7. data/lib/active_support/array_inquirer.rb +50 -0
  8. data/lib/active_support/backtrace_cleaner.rb +234 -0
  9. data/lib/active_support/benchmark.rb +21 -0
  10. data/lib/active_support/benchmarkable.rb +53 -0
  11. data/lib/active_support/broadcast_logger.rb +238 -0
  12. data/lib/active_support/builder.rb +8 -0
  13. data/lib/active_support/cache/coder.rb +153 -0
  14. data/lib/active_support/cache/entry.rb +134 -0
  15. data/lib/active_support/cache/file_store.rb +244 -0
  16. data/lib/active_support/cache/mem_cache_store.rb +288 -0
  17. data/lib/active_support/cache/memory_store.rb +264 -0
  18. data/lib/active_support/cache/null_store.rb +62 -0
  19. data/lib/active_support/cache/redis_cache_store.rb +498 -0
  20. data/lib/active_support/cache/serializer_with_fallback.rb +152 -0
  21. data/lib/active_support/cache/strategy/local_cache.rb +246 -0
  22. data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
  23. data/lib/active_support/cache.rb +1170 -0
  24. data/lib/active_support/callbacks.rb +960 -0
  25. data/lib/active_support/class_attribute.rb +33 -0
  26. data/lib/active_support/code_generator.rb +79 -0
  27. data/lib/active_support/concern.rb +217 -0
  28. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
  29. data/lib/active_support/concurrency/null_lock.rb +13 -0
  30. data/lib/active_support/concurrency/share_lock.rb +225 -0
  31. data/lib/active_support/concurrency/thread_monitor.rb +55 -0
  32. data/lib/active_support/configurable.rb +193 -0
  33. data/lib/active_support/configuration_file.rb +60 -0
  34. data/lib/active_support/continuous_integration.rb +145 -0
  35. data/lib/active_support/core_ext/array/access.rb +100 -0
  36. data/lib/active_support/core_ext/array/conversions.rb +209 -26
  37. data/lib/active_support/core_ext/array/extract.rb +21 -0
  38. data/lib/active_support/core_ext/array/extract_options.rb +31 -0
  39. data/lib/active_support/core_ext/array/grouping.rb +109 -0
  40. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  41. data/lib/active_support/core_ext/array/wrap.rb +48 -0
  42. data/lib/active_support/core_ext/array.rb +8 -4
  43. data/lib/active_support/core_ext/benchmark.rb +6 -0
  44. data/lib/active_support/core_ext/big_decimal/conversions.rb +14 -0
  45. data/lib/active_support/core_ext/big_decimal.rb +3 -0
  46. data/lib/active_support/core_ext/class/attribute.rb +137 -0
  47. data/lib/active_support/core_ext/class/attribute_accessors.rb +6 -0
  48. data/lib/active_support/core_ext/class/subclasses.rb +24 -0
  49. data/lib/active_support/core_ext/class.rb +4 -0
  50. data/lib/active_support/core_ext/date/acts_like.rb +10 -0
  51. data/lib/active_support/core_ext/date/blank.rb +18 -0
  52. data/lib/active_support/core_ext/date/calculations.rb +161 -0
  53. data/lib/active_support/core_ext/date/conversions.rb +95 -28
  54. data/lib/active_support/core_ext/date/zones.rb +8 -0
  55. data/lib/active_support/core_ext/date.rb +6 -5
  56. data/lib/active_support/core_ext/date_and_time/calculations.rb +374 -0
  57. data/lib/active_support/core_ext/date_and_time/compatibility.rb +23 -0
  58. data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
  59. data/lib/active_support/core_ext/date_time/acts_like.rb +16 -0
  60. data/lib/active_support/core_ext/date_time/blank.rb +18 -0
  61. data/lib/active_support/core_ext/date_time/calculations.rb +215 -0
  62. data/lib/active_support/core_ext/date_time/compatibility.rb +16 -0
  63. data/lib/active_support/core_ext/date_time/conversions.rb +108 -0
  64. data/lib/active_support/core_ext/date_time.rb +7 -0
  65. data/lib/active_support/core_ext/digest/uuid.rb +76 -0
  66. data/lib/active_support/core_ext/digest.rb +3 -0
  67. data/lib/active_support/core_ext/enumerable.rb +277 -7
  68. data/lib/active_support/core_ext/erb/util.rb +201 -0
  69. data/lib/active_support/core_ext/file/atomic.rb +72 -0
  70. data/lib/active_support/core_ext/file.rb +3 -0
  71. data/lib/active_support/core_ext/hash/conversions.rb +262 -0
  72. data/lib/active_support/core_ext/hash/deep_merge.rb +43 -0
  73. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  74. data/lib/active_support/core_ext/hash/except.rb +12 -0
  75. data/lib/active_support/core_ext/hash/indifferent_access.rb +19 -55
  76. data/lib/active_support/core_ext/hash/keys.rb +134 -44
  77. data/lib/active_support/core_ext/hash/reverse_merge.rb +22 -22
  78. data/lib/active_support/core_ext/hash/slice.rb +27 -0
  79. data/lib/active_support/core_ext/hash.rb +9 -8
  80. data/lib/active_support/core_ext/integer/inflections.rb +29 -13
  81. data/lib/active_support/core_ext/integer/multiple.rb +12 -0
  82. data/lib/active_support/core_ext/integer/time.rb +22 -0
  83. data/lib/active_support/core_ext/integer.rb +4 -6
  84. data/lib/active_support/core_ext/kernel/concern.rb +14 -0
  85. data/lib/active_support/core_ext/kernel/reporting.rb +45 -0
  86. data/lib/active_support/core_ext/kernel/singleton_class.rb +8 -0
  87. data/lib/active_support/core_ext/kernel.rb +4 -78
  88. data/lib/active_support/core_ext/load_error.rb +6 -35
  89. data/lib/active_support/core_ext/module/aliasing.rb +31 -0
  90. data/lib/active_support/core_ext/module/anonymous.rb +30 -0
  91. data/lib/active_support/core_ext/module/attr_internal.rb +48 -0
  92. data/lib/active_support/core_ext/module/attribute_accessors.rb +214 -0
  93. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +175 -0
  94. data/lib/active_support/core_ext/module/concerning.rb +140 -0
  95. data/lib/active_support/core_ext/module/delegation.rb +225 -0
  96. data/lib/active_support/core_ext/module/deprecation.rb +25 -0
  97. data/lib/active_support/core_ext/module/introspection.rb +65 -0
  98. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  99. data/lib/active_support/core_ext/module/remove_method.rb +17 -0
  100. data/lib/active_support/core_ext/module.rb +13 -0
  101. data/lib/active_support/core_ext/name_error.rb +59 -0
  102. data/lib/active_support/core_ext/numeric/bytes.rb +73 -42
  103. data/lib/active_support/core_ext/numeric/conversions.rb +145 -0
  104. data/lib/active_support/core_ext/numeric/time.rb +64 -57
  105. data/lib/active_support/core_ext/numeric.rb +4 -6
  106. data/lib/active_support/core_ext/object/acts_like.rb +45 -0
  107. data/lib/active_support/core_ext/object/blank.rb +199 -0
  108. data/lib/active_support/core_ext/object/conversions.rb +6 -0
  109. data/lib/active_support/core_ext/object/deep_dup.rb +71 -0
  110. data/lib/active_support/core_ext/object/duplicable.rb +69 -0
  111. data/lib/active_support/core_ext/object/inclusion.rb +37 -0
  112. data/lib/active_support/core_ext/object/instance_variables.rb +32 -0
  113. data/lib/active_support/core_ext/object/json.rb +267 -0
  114. data/lib/active_support/core_ext/object/to_param.rb +3 -0
  115. data/lib/active_support/core_ext/object/to_query.rb +93 -0
  116. data/lib/active_support/core_ext/object/try.rb +158 -0
  117. data/lib/active_support/core_ext/object/with.rb +46 -0
  118. data/lib/active_support/core_ext/object/with_options.rb +101 -0
  119. data/lib/active_support/core_ext/object.rb +17 -0
  120. data/lib/active_support/core_ext/pathname/blank.rb +20 -0
  121. data/lib/active_support/core_ext/pathname/existence.rb +23 -0
  122. data/lib/active_support/core_ext/pathname.rb +4 -0
  123. data/lib/active_support/core_ext/range/compare_range.rb +57 -0
  124. data/lib/active_support/core_ext/range/conversions.rb +58 -17
  125. data/lib/active_support/core_ext/range/overlap.rb +40 -0
  126. data/lib/active_support/core_ext/range/sole.rb +17 -0
  127. data/lib/active_support/core_ext/range.rb +5 -4
  128. data/lib/active_support/core_ext/regexp.rb +14 -0
  129. data/lib/active_support/core_ext/securerandom.rb +57 -0
  130. data/lib/active_support/core_ext/string/access.rb +93 -56
  131. data/lib/active_support/core_ext/string/behavior.rb +8 -0
  132. data/lib/active_support/core_ext/string/conversions.rb +57 -16
  133. data/lib/active_support/core_ext/string/exclude.rb +13 -0
  134. data/lib/active_support/core_ext/string/filters.rb +151 -0
  135. data/lib/active_support/core_ext/string/indent.rb +45 -0
  136. data/lib/active_support/core_ext/string/inflections.rb +297 -54
  137. data/lib/active_support/core_ext/string/inquiry.rb +16 -0
  138. data/lib/active_support/core_ext/string/multibyte.rb +67 -0
  139. data/lib/active_support/core_ext/string/output_safety.rb +235 -0
  140. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -18
  141. data/lib/active_support/core_ext/string/strip.rb +27 -0
  142. data/lib/active_support/core_ext/string/zones.rb +16 -0
  143. data/lib/active_support/core_ext/string.rb +14 -10
  144. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
  145. data/lib/active_support/core_ext/symbol.rb +3 -0
  146. data/lib/active_support/core_ext/thread/backtrace/location.rb +7 -0
  147. data/lib/active_support/core_ext/time/acts_like.rb +10 -0
  148. data/lib/active_support/core_ext/time/calculations.rb +358 -153
  149. data/lib/active_support/core_ext/time/compatibility.rb +15 -0
  150. data/lib/active_support/core_ext/time/conversions.rb +69 -30
  151. data/lib/active_support/core_ext/time/zones.rb +97 -0
  152. data/lib/active_support/core_ext/time.rb +6 -6
  153. data/lib/active_support/core_ext.rb +5 -1
  154. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  155. data/lib/active_support/current_attributes.rb +243 -0
  156. data/lib/active_support/deep_mergeable.rb +53 -0
  157. data/lib/active_support/delegation.rb +183 -0
  158. data/lib/active_support/dependencies/autoload.rb +72 -0
  159. data/lib/active_support/dependencies/interlock.rb +55 -0
  160. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  161. data/lib/active_support/dependencies.rb +84 -222
  162. data/lib/active_support/deprecation/behaviors.rb +148 -0
  163. data/lib/active_support/deprecation/constant_accessor.rb +74 -0
  164. data/lib/active_support/deprecation/deprecators.rb +104 -0
  165. data/lib/active_support/deprecation/disallowed.rb +54 -0
  166. data/lib/active_support/deprecation/method_wrappers.rb +68 -0
  167. data/lib/active_support/deprecation/proxy_wrappers.rb +189 -0
  168. data/lib/active_support/deprecation/reporting.rb +162 -0
  169. data/lib/active_support/deprecation.rb +81 -0
  170. data/lib/active_support/deprecator.rb +7 -0
  171. data/lib/active_support/descendants_tracker.rb +112 -0
  172. data/lib/active_support/digest.rb +22 -0
  173. data/lib/active_support/duration/iso8601_parser.rb +123 -0
  174. data/lib/active_support/duration/iso8601_serializer.rb +64 -0
  175. data/lib/active_support/duration.rb +524 -0
  176. data/lib/active_support/editor.rb +70 -0
  177. data/lib/active_support/encrypted_configuration.rb +126 -0
  178. data/lib/active_support/encrypted_file.rb +133 -0
  179. data/lib/active_support/environment_inquirer.rb +40 -0
  180. data/lib/active_support/error_reporter/test_helper.rb +15 -0
  181. data/lib/active_support/error_reporter.rb +318 -0
  182. data/lib/active_support/event_reporter/test_helper.rb +32 -0
  183. data/lib/active_support/event_reporter.rb +592 -0
  184. data/lib/active_support/evented_file_update_checker.rb +185 -0
  185. data/lib/active_support/execution_context/test_helper.rb +13 -0
  186. data/lib/active_support/execution_context.rb +110 -0
  187. data/lib/active_support/execution_wrapper.rb +150 -0
  188. data/lib/active_support/executor/test_helper.rb +7 -0
  189. data/lib/active_support/executor.rb +8 -0
  190. data/lib/active_support/file_update_checker.rb +166 -0
  191. data/lib/active_support/fork_tracker.rb +43 -0
  192. data/lib/active_support/gem_version.rb +17 -0
  193. data/lib/active_support/gzip.rb +41 -0
  194. data/lib/active_support/hash_with_indifferent_access.rb +464 -0
  195. data/lib/active_support/html_safe_translation.rb +56 -0
  196. data/lib/active_support/i18n.rb +17 -0
  197. data/lib/active_support/i18n_railtie.rb +140 -0
  198. data/lib/active_support/inflections.rb +68 -49
  199. data/lib/active_support/inflector/inflections.rb +290 -0
  200. data/lib/active_support/inflector/methods.rb +387 -0
  201. data/lib/active_support/inflector/transliterate.rb +147 -0
  202. data/lib/active_support/inflector.rb +7 -164
  203. data/lib/active_support/isolated_execution_state.rb +76 -0
  204. data/lib/active_support/json/decoding.rb +78 -0
  205. data/lib/active_support/json/encoding.rb +256 -0
  206. data/lib/active_support/json.rb +4 -0
  207. data/lib/active_support/key_generator.rb +66 -0
  208. data/lib/active_support/lazy_load_hooks.rb +107 -0
  209. data/lib/active_support/locale/en.rb +33 -0
  210. data/lib/active_support/locale/en.yml +141 -0
  211. data/lib/active_support/log_subscriber/test_helper.rb +106 -0
  212. data/lib/active_support/log_subscriber.rb +188 -0
  213. data/lib/active_support/logger.rb +55 -0
  214. data/lib/active_support/logger_silence.rb +21 -0
  215. data/lib/active_support/logger_thread_safe_level.rb +50 -0
  216. data/lib/active_support/message_encryptor.rb +374 -0
  217. data/lib/active_support/message_encryptors.rb +193 -0
  218. data/lib/active_support/message_pack/cache_serializer.rb +23 -0
  219. data/lib/active_support/message_pack/extensions.rb +310 -0
  220. data/lib/active_support/message_pack/serializer.rb +63 -0
  221. data/lib/active_support/message_pack.rb +50 -0
  222. data/lib/active_support/message_verifier.rb +377 -0
  223. data/lib/active_support/message_verifiers.rb +189 -0
  224. data/lib/active_support/messages/codec.rb +65 -0
  225. data/lib/active_support/messages/metadata.rb +146 -0
  226. data/lib/active_support/messages/rotation_configuration.rb +23 -0
  227. data/lib/active_support/messages/rotation_coordinator.rb +102 -0
  228. data/lib/active_support/messages/rotator.rb +69 -0
  229. data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
  230. data/lib/active_support/multibyte/chars.rb +188 -0
  231. data/lib/active_support/multibyte/unicode.rb +42 -0
  232. data/lib/active_support/multibyte.rb +27 -0
  233. data/lib/active_support/notifications/fanout.rb +467 -0
  234. data/lib/active_support/notifications/instrumenter.rb +240 -0
  235. data/lib/active_support/notifications.rb +281 -0
  236. data/lib/active_support/number_helper/number_converter.rb +190 -0
  237. data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
  238. data/lib/active_support/number_helper/number_to_delimited_converter.rb +30 -0
  239. data/lib/active_support/number_helper/number_to_human_converter.rb +69 -0
  240. data/lib/active_support/number_helper/number_to_human_size_converter.rb +60 -0
  241. data/lib/active_support/number_helper/number_to_percentage_converter.rb +16 -0
  242. data/lib/active_support/number_helper/number_to_phone_converter.rb +60 -0
  243. data/lib/active_support/number_helper/number_to_rounded_converter.rb +59 -0
  244. data/lib/active_support/number_helper/rounding_helper.rb +46 -0
  245. data/lib/active_support/number_helper.rb +479 -0
  246. data/lib/active_support/option_merger.rb +38 -0
  247. data/lib/active_support/ordered_hash.rb +50 -0
  248. data/lib/active_support/ordered_options.rb +141 -25
  249. data/lib/active_support/parameter_filter.rb +157 -0
  250. data/lib/active_support/rails.rb +26 -0
  251. data/lib/active_support/railtie.rb +180 -0
  252. data/lib/active_support/reloader.rb +138 -0
  253. data/lib/active_support/rescuable.rb +176 -0
  254. data/lib/active_support/secure_compare_rotator.rb +58 -0
  255. data/lib/active_support/security_utils.rb +38 -0
  256. data/lib/active_support/string_inquirer.rb +35 -0
  257. data/lib/active_support/structured_event_subscriber.rb +99 -0
  258. data/lib/active_support/subscriber.rb +141 -0
  259. data/lib/active_support/syntax_error_proxy.rb +67 -0
  260. data/lib/active_support/tagged_logging.rb +157 -0
  261. data/lib/active_support/test_case.rb +365 -0
  262. data/lib/active_support/testing/assertions.rb +369 -0
  263. data/lib/active_support/testing/autorun.rb +10 -0
  264. data/lib/active_support/testing/constant_lookup.rb +51 -0
  265. data/lib/active_support/testing/constant_stubbing.rb +54 -0
  266. data/lib/active_support/testing/declarative.rb +28 -0
  267. data/lib/active_support/testing/deprecation.rb +82 -0
  268. data/lib/active_support/testing/error_reporter_assertions.rb +124 -0
  269. data/lib/active_support/testing/event_reporter_assertions.rb +227 -0
  270. data/lib/active_support/testing/file_fixtures.rb +38 -0
  271. data/lib/active_support/testing/isolation.rb +121 -0
  272. data/lib/active_support/testing/method_call_assertions.rb +69 -0
  273. data/lib/active_support/testing/notification_assertions.rb +92 -0
  274. data/lib/active_support/testing/parallelization/server.rb +98 -0
  275. data/lib/active_support/testing/parallelization/worker.rb +107 -0
  276. data/lib/active_support/testing/parallelization.rb +79 -0
  277. data/lib/active_support/testing/parallelize_executor.rb +81 -0
  278. data/lib/active_support/testing/setup_and_teardown.rb +57 -0
  279. data/lib/active_support/testing/stream.rb +41 -0
  280. data/lib/active_support/testing/tagged_logging.rb +27 -0
  281. data/lib/active_support/testing/tests_without_assertions.rb +19 -0
  282. data/lib/active_support/testing/time_helpers.rb +273 -0
  283. data/lib/active_support/time.rb +20 -0
  284. data/lib/active_support/time_with_zone.rb +613 -0
  285. data/lib/active_support/values/time_zone.rb +599 -158
  286. data/lib/active_support/version.rb +7 -6
  287. data/lib/active_support/xml_mini/jdom.rb +175 -0
  288. data/lib/active_support/xml_mini/libxml.rb +80 -0
  289. data/lib/active_support/xml_mini/libxmlsax.rb +83 -0
  290. data/lib/active_support/xml_mini/nokogiri.rb +83 -0
  291. data/lib/active_support/xml_mini/nokogirisax.rb +86 -0
  292. data/lib/active_support/xml_mini/rexml.rb +137 -0
  293. data/lib/active_support/xml_mini.rb +212 -0
  294. data/lib/active_support.rb +122 -10
  295. metadata +524 -93
  296. data/CHANGELOG +0 -283
  297. data/lib/active_support/binding_of_caller.rb +0 -84
  298. data/lib/active_support/breakpoint.rb +0 -523
  299. data/lib/active_support/class_attribute_accessors.rb +0 -57
  300. data/lib/active_support/class_inheritable_attributes.rb +0 -117
  301. data/lib/active_support/clean_logger.rb +0 -36
  302. data/lib/active_support/core_ext/blank.rb +0 -38
  303. data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +0 -14
  304. data/lib/active_support/core_ext/cgi.rb +0 -5
  305. data/lib/active_support/core_ext/exception.rb +0 -29
  306. data/lib/active_support/core_ext/integer/even_odd.rb +0 -24
  307. data/lib/active_support/core_ext/object_and_class.rb +0 -44
  308. data/lib/active_support/module_attribute_accessors.rb +0 -57
  309. data/lib/active_support/whiny_nil.rb +0 -38
@@ -0,0 +1,273 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/module/redefine_method"
4
+ require "active_support/core_ext/time/calculations"
5
+
6
+ module ActiveSupport
7
+ module Testing
8
+ # Manages stubs for TimeHelpers
9
+ class SimpleStubs # :nodoc:
10
+ Stub = Struct.new(:object, :method_name, :original_method)
11
+
12
+ def initialize
13
+ @stubs = Hash.new { |h, k| h[k] = {} }
14
+ end
15
+
16
+ # Stubs object.method_name with the given block
17
+ # If the method is already stubbed, remove that stub
18
+ # so that removing this stub will restore the original implementation.
19
+ # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
20
+ # target = Time.zone.local(2004, 11, 24, 1, 4, 44)
21
+ # simple_stubs.stub_object(Time, :now) { at(target.to_i) }
22
+ # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
23
+ def stub_object(object, method_name, &block)
24
+ if stub = stubbing(object, method_name)
25
+ unstub_object(stub)
26
+ end
27
+
28
+ new_name = "__simple_stub__#{method_name}__#{object_id}"
29
+
30
+ @stubs[object.object_id][method_name] = Stub.new(object, method_name, new_name)
31
+
32
+ object.singleton_class.alias_method new_name, method_name
33
+ object.define_singleton_method(method_name, &block)
34
+ end
35
+
36
+ # Remove all object-method stubs held by this instance
37
+ def unstub_all!
38
+ @stubs.each_value do |object_stubs|
39
+ object_stubs.each_value do |stub|
40
+ unstub_object(stub)
41
+ end
42
+ end
43
+ @stubs.clear
44
+ end
45
+
46
+ # Returns the Stub for object#method_name
47
+ # (nil if it is not stubbed)
48
+ def stubbing(object, method_name)
49
+ @stubs[object.object_id][method_name]
50
+ end
51
+
52
+ # Returns true if any stubs are set, false if there are none
53
+ def stubbed?
54
+ !@stubs.empty?
55
+ end
56
+
57
+ private
58
+ # Restores the original object.method described by the Stub
59
+ def unstub_object(stub)
60
+ singleton_class = stub.object.singleton_class
61
+ singleton_class.silence_redefinition_of_method stub.method_name
62
+ singleton_class.alias_method stub.method_name, stub.original_method
63
+ singleton_class.undef_method stub.original_method
64
+ end
65
+ end
66
+
67
+ # Contains helpers that help you test passage of time.
68
+ module TimeHelpers
69
+ def after_teardown
70
+ travel_back
71
+ super
72
+ end
73
+
74
+ # Changes current time to the time in the future or in the past by a given time difference by
75
+ # stubbing +Time.now+, +Date.today+, and +DateTime.now+. The stubs are automatically removed
76
+ # at the end of the test.
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
+ #
83
+ # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
84
+ # travel 1.day
85
+ # Time.current # => Sun, 10 Nov 2013 15:34:49 EST -05:00
86
+ # Date.current # => Sun, 10 Nov 2013
87
+ # DateTime.current # => Sun, 10 Nov 2013 15:34:49 -0500
88
+ #
89
+ # This method also accepts a block, which will return the current time back to its original
90
+ # state at the end of the block:
91
+ #
92
+ # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
93
+ # travel 1.day do
94
+ # User.create.created_at # => Sun, 10 Nov 2013 15:34:49 EST -05:00
95
+ # end
96
+ # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
97
+ def travel(duration, with_usec: false, &block)
98
+ travel_to Time.now + duration, with_usec: with_usec, &block
99
+ end
100
+
101
+ # Changes current time to the given time by stubbing +Time.now+, +Time.new+,
102
+ # +Date.today+, and +DateTime.now+ to return the time or date passed into this method.
103
+ # The stubs are automatically removed at the end of the test.
104
+ #
105
+ # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
106
+ # travel_to Time.zone.local(2004, 11, 24, 1, 4, 44)
107
+ # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
108
+ # Date.current # => Wed, 24 Nov 2004
109
+ # DateTime.current # => Wed, 24 Nov 2004 01:04:44 -0500
110
+ #
111
+ # Dates are taken as their timestamp at the beginning of the day in the
112
+ # application time zone. <tt>Time.current</tt> returns said timestamp,
113
+ # and <tt>Time.now</tt> its equivalent in the system time zone. Similarly,
114
+ # <tt>Date.current</tt> returns a date equal to the argument, and
115
+ # <tt>Date.today</tt> the date according to <tt>Time.now</tt>, which may
116
+ # be different. (Note that you rarely want to deal with <tt>Time.now</tt>,
117
+ # or <tt>Date.today</tt>, in order to honor the application time zone
118
+ # please always use <tt>Time.current</tt> and <tt>Date.current</tt>.)
119
+ #
120
+ # Note that the usec for the time passed will be set to 0 to prevent rounding
121
+ # errors with external services, like MySQL (which will round instead of floor,
122
+ # leading to off-by-one-second errors), unless the <tt>with_usec</tt> argument
123
+ # is set to <tt>true</tt>.
124
+ #
125
+ # This method also accepts a block, which will return the current time back to its original
126
+ # state at the end of the block:
127
+ #
128
+ # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
129
+ # travel_to Time.zone.local(2004, 11, 24, 1, 4, 44) do
130
+ # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
131
+ # end
132
+ # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
133
+ def travel_to(date_or_time, with_usec: false)
134
+ if block_given? && in_block
135
+ travel_to_nested_block_call = <<~MSG
136
+
137
+ Calling `travel_to` with a block, when we have previously already made a call to `travel_to`, can lead to confusing time stubbing.
138
+
139
+ Instead of:
140
+
141
+ travel_to 2.days.from_now do
142
+ # 2 days from today
143
+ travel_to 3.days.from_now do
144
+ # 5 days from today
145
+ end
146
+ end
147
+
148
+ preferred way to achieve above is:
149
+
150
+ travel 2.days do
151
+ # 2 days from today
152
+ end
153
+
154
+ travel 5.days do
155
+ # 5 days from today
156
+ end
157
+
158
+ MSG
159
+ raise travel_to_nested_block_call
160
+ end
161
+
162
+ if date_or_time.is_a?(Date) && !date_or_time.is_a?(DateTime)
163
+ now = date_or_time.midnight.to_time
164
+ elsif date_or_time.is_a?(String)
165
+ now = Time.zone.parse(date_or_time)
166
+ else
167
+ now = date_or_time
168
+ now = now.to_time unless now.is_a?(Time)
169
+ end
170
+
171
+ now = now.change(usec: 0) unless with_usec
172
+
173
+ # +now+ must be in local system timezone, because +Time.at(now)+
174
+ # and +now.to_date+ (see stubs below) will use +now+'s timezone too!
175
+ now = now.getlocal
176
+
177
+ stubs = simple_stubs
178
+ stubbed_time = Time.now if stubs.stubbing(Time, :now)
179
+ stubs.stub_object(Time, :now) { at(now) }
180
+
181
+ stubs.stub_object(Time, :new) do |*args, **options|
182
+ if args.empty? && options.empty?
183
+ at(now)
184
+ else
185
+ stub = stubs.stubbing(Time, :new)
186
+ Time.send(stub.original_method, *args, **options)
187
+ end
188
+ end
189
+
190
+ stubs.stub_object(Date, :today) { jd(now.to_date.jd) }
191
+ stubs.stub_object(DateTime, :now) { jd(now.to_date.jd, now.hour, now.min, now.sec, Rational(now.utc_offset, 86400)) }
192
+
193
+ if block_given?
194
+ begin
195
+ self.in_block = true
196
+ yield
197
+ ensure
198
+ if stubbed_time
199
+ travel_to stubbed_time
200
+ else
201
+ travel_back
202
+ end
203
+ self.in_block = false
204
+ end
205
+ end
206
+ end
207
+
208
+ # Returns the current time back to its original state, by removing the stubs added by
209
+ # +travel+, +travel_to+, and +freeze_time+.
210
+ #
211
+ # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
212
+ #
213
+ # travel_to Time.zone.local(2004, 11, 24, 1, 4, 44)
214
+ # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
215
+ #
216
+ # travel_back
217
+ # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
218
+ #
219
+ # This method also accepts a block, which brings the stubs back at the end of the block:
220
+ #
221
+ # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
222
+ #
223
+ # travel_to Time.zone.local(2004, 11, 24, 1, 4, 44)
224
+ # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
225
+ #
226
+ # travel_back do
227
+ # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
228
+ # end
229
+ #
230
+ # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
231
+ def travel_back
232
+ stubbed_time = Time.current if block_given? && simple_stubs.stubbed?
233
+
234
+ simple_stubs.unstub_all!
235
+ yield if block_given?
236
+ ensure
237
+ travel_to stubbed_time if stubbed_time
238
+ end
239
+ alias_method :unfreeze_time, :travel_back
240
+
241
+ # Calls +travel_to+ with +date_or_time+, which defaults to +Time.now+.
242
+ # Forwards optional <tt>with_usec</tt> argument.
243
+ #
244
+ # Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00
245
+ # freeze_time
246
+ # sleep(1)
247
+ # Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00
248
+ # freeze_time Time.current + 1.day
249
+ # sleep(1)
250
+ # Time.current # => Mon, 10 Jul 2017 15:34:49 EST -05:00
251
+ #
252
+ # This method also accepts a block, which will return the current time back to its original
253
+ # state at the end of the block:
254
+ #
255
+ # Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00
256
+ # freeze_time do
257
+ # sleep(1)
258
+ # User.create.created_at # => Sun, 09 Jul 2017 15:34:49 EST -05:00
259
+ # end
260
+ # Time.current # => Sun, 09 Jul 2017 15:34:50 EST -05:00
261
+ def freeze_time(date_or_time = Time.now, with_usec: false, &block)
262
+ travel_to date_or_time, with_usec: with_usec, &block
263
+ end
264
+
265
+ private
266
+ def simple_stubs
267
+ @simple_stubs ||= SimpleStubs.new
268
+ end
269
+
270
+ attr_accessor :in_block
271
+ end
272
+ end
273
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ autoload :Duration, "active_support/duration"
5
+ autoload :TimeWithZone, "active_support/time_with_zone"
6
+ autoload :TimeZone, "active_support/values/time_zone"
7
+ end
8
+
9
+ require "date"
10
+ require "time"
11
+
12
+ require "active_support/core_ext/time"
13
+ require "active_support/core_ext/date"
14
+ require "active_support/core_ext/date_time"
15
+
16
+ require "active_support/core_ext/integer/time"
17
+ require "active_support/core_ext/numeric/time"
18
+
19
+ require "active_support/core_ext/string/conversions"
20
+ require "active_support/core_ext/string/zones"