activesupport 5.1.7 → 6.1.7

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 (262) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +434 -490
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +6 -5
  5. data/lib/active_support/actionable_error.rb +48 -0
  6. data/lib/active_support/all.rb +2 -0
  7. data/lib/active_support/array_inquirer.rb +6 -2
  8. data/lib/active_support/backtrace_cleaner.rb +31 -3
  9. data/lib/active_support/benchmarkable.rb +3 -1
  10. data/lib/active_support/builder.rb +2 -0
  11. data/lib/active_support/cache/file_store.rb +37 -36
  12. data/lib/active_support/cache/mem_cache_store.rb +72 -56
  13. data/lib/active_support/cache/memory_store.rb +61 -33
  14. data/lib/active_support/cache/null_store.rb +10 -3
  15. data/lib/active_support/cache/redis_cache_store.rb +493 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +67 -21
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
  18. data/lib/active_support/cache.rb +310 -126
  19. data/lib/active_support/callbacks.rb +106 -100
  20. data/lib/active_support/concern.rb +79 -6
  21. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
  22. data/lib/active_support/concurrency/share_lock.rb +2 -1
  23. data/lib/active_support/configurable.rb +12 -14
  24. data/lib/active_support/configuration_file.rb +51 -0
  25. data/lib/active_support/core_ext/array/access.rb +21 -7
  26. data/lib/active_support/core_ext/array/conversions.rb +7 -5
  27. data/lib/active_support/core_ext/array/extract.rb +21 -0
  28. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  29. data/lib/active_support/core_ext/array/grouping.rb +2 -0
  30. data/lib/active_support/core_ext/array/inquiry.rb +2 -0
  31. data/lib/active_support/core_ext/array/wrap.rb +2 -0
  32. data/lib/active_support/core_ext/array.rb +3 -1
  33. data/lib/active_support/core_ext/benchmark.rb +4 -2
  34. data/lib/active_support/core_ext/big_decimal/conversions.rb +2 -0
  35. data/lib/active_support/core_ext/big_decimal.rb +2 -0
  36. data/lib/active_support/core_ext/class/attribute.rb +50 -47
  37. data/lib/active_support/core_ext/class/attribute_accessors.rb +2 -0
  38. data/lib/active_support/core_ext/class/subclasses.rb +18 -40
  39. data/lib/active_support/core_ext/class.rb +2 -0
  40. data/lib/active_support/core_ext/date/acts_like.rb +2 -0
  41. data/lib/active_support/core_ext/date/blank.rb +2 -0
  42. data/lib/active_support/core_ext/date/calculations.rb +8 -5
  43. data/lib/active_support/core_ext/date/conversions.rb +12 -10
  44. data/lib/active_support/core_ext/date/zones.rb +2 -0
  45. data/lib/active_support/core_ext/date.rb +2 -0
  46. data/lib/active_support/core_ext/date_and_time/calculations.rb +61 -37
  47. data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -1
  48. data/lib/active_support/core_ext/date_and_time/zones.rb +2 -1
  49. data/lib/active_support/core_ext/date_time/acts_like.rb +2 -0
  50. data/lib/active_support/core_ext/date_time/blank.rb +2 -0
  51. data/lib/active_support/core_ext/date_time/calculations.rb +3 -1
  52. data/lib/active_support/core_ext/date_time/compatibility.rb +7 -5
  53. data/lib/active_support/core_ext/date_time/conversions.rb +2 -1
  54. data/lib/active_support/core_ext/date_time.rb +2 -0
  55. data/lib/active_support/core_ext/digest/uuid.rb +4 -1
  56. data/lib/active_support/core_ext/digest.rb +3 -0
  57. data/lib/active_support/core_ext/enumerable.rb +174 -71
  58. data/lib/active_support/core_ext/file/atomic.rb +3 -1
  59. data/lib/active_support/core_ext/file.rb +2 -0
  60. data/lib/active_support/core_ext/hash/conversions.rb +7 -5
  61. data/lib/active_support/core_ext/hash/deep_merge.rb +8 -12
  62. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  63. data/lib/active_support/core_ext/hash/except.rb +4 -2
  64. data/lib/active_support/core_ext/hash/indifferent_access.rb +2 -0
  65. data/lib/active_support/core_ext/hash/keys.rb +3 -30
  66. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  67. data/lib/active_support/core_ext/hash/slice.rb +8 -29
  68. data/lib/active_support/core_ext/hash.rb +3 -2
  69. data/lib/active_support/core_ext/integer/inflections.rb +2 -0
  70. data/lib/active_support/core_ext/integer/multiple.rb +3 -1
  71. data/lib/active_support/core_ext/integer/time.rb +7 -14
  72. data/lib/active_support/core_ext/integer.rb +2 -0
  73. data/lib/active_support/core_ext/kernel/concern.rb +2 -0
  74. data/lib/active_support/core_ext/kernel/reporting.rb +2 -0
  75. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  76. data/lib/active_support/core_ext/kernel.rb +2 -1
  77. data/lib/active_support/core_ext/load_error.rb +3 -8
  78. data/lib/active_support/core_ext/marshal.rb +4 -0
  79. data/lib/active_support/core_ext/module/aliasing.rb +2 -0
  80. data/lib/active_support/core_ext/module/anonymous.rb +2 -0
  81. data/lib/active_support/core_ext/module/attr_internal.rb +4 -2
  82. data/lib/active_support/core_ext/module/attribute_accessors.rb +44 -56
  83. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +18 -18
  84. data/lib/active_support/core_ext/module/concerning.rb +15 -10
  85. data/lib/active_support/core_ext/module/delegation.rb +103 -58
  86. data/lib/active_support/core_ext/module/deprecation.rb +2 -0
  87. data/lib/active_support/core_ext/module/introspection.rb +18 -15
  88. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  89. data/lib/active_support/core_ext/module/remove_method.rb +5 -23
  90. data/lib/active_support/core_ext/module.rb +3 -1
  91. data/lib/active_support/core_ext/name_error.rb +36 -2
  92. data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
  93. data/lib/active_support/core_ext/numeric/conversions.rb +131 -129
  94. data/lib/active_support/core_ext/numeric/time.rb +7 -15
  95. data/lib/active_support/core_ext/numeric.rb +2 -1
  96. data/lib/active_support/core_ext/object/acts_like.rb +12 -1
  97. data/lib/active_support/core_ext/object/blank.rb +13 -3
  98. data/lib/active_support/core_ext/object/conversions.rb +2 -0
  99. data/lib/active_support/core_ext/object/deep_dup.rb +3 -1
  100. data/lib/active_support/core_ext/object/duplicable.rb +9 -114
  101. data/lib/active_support/core_ext/object/inclusion.rb +2 -0
  102. data/lib/active_support/core_ext/object/instance_variables.rb +2 -0
  103. data/lib/active_support/core_ext/object/json.rb +22 -2
  104. data/lib/active_support/core_ext/object/to_param.rb +2 -0
  105. data/lib/active_support/core_ext/object/to_query.rb +2 -0
  106. data/lib/active_support/core_ext/object/try.rb +19 -7
  107. data/lib/active_support/core_ext/object/with_options.rb +4 -2
  108. data/lib/active_support/core_ext/object.rb +2 -0
  109. data/lib/active_support/core_ext/range/compare_range.rb +82 -0
  110. data/lib/active_support/core_ext/range/conversions.rb +35 -25
  111. data/lib/active_support/core_ext/range/each.rb +5 -2
  112. data/lib/active_support/core_ext/range/include_time_with_zone.rb +28 -0
  113. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  114. data/lib/active_support/core_ext/range.rb +4 -1
  115. data/lib/active_support/core_ext/regexp.rb +10 -5
  116. data/lib/active_support/core_ext/securerandom.rb +25 -3
  117. data/lib/active_support/core_ext/string/access.rb +7 -16
  118. data/lib/active_support/core_ext/string/behavior.rb +2 -0
  119. data/lib/active_support/core_ext/string/conversions.rb +3 -0
  120. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  121. data/lib/active_support/core_ext/string/filters.rb +44 -1
  122. data/lib/active_support/core_ext/string/indent.rb +2 -0
  123. data/lib/active_support/core_ext/string/inflections.rb +69 -16
  124. data/lib/active_support/core_ext/string/inquiry.rb +3 -0
  125. data/lib/active_support/core_ext/string/multibyte.rb +9 -4
  126. data/lib/active_support/core_ext/string/output_safety.rb +104 -20
  127. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
  128. data/lib/active_support/core_ext/string/strip.rb +5 -1
  129. data/lib/active_support/core_ext/string/zones.rb +2 -0
  130. data/lib/active_support/core_ext/string.rb +2 -0
  131. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +14 -0
  132. data/lib/active_support/core_ext/symbol.rb +3 -0
  133. data/lib/active_support/core_ext/time/acts_like.rb +2 -0
  134. data/lib/active_support/core_ext/time/calculations.rb +76 -18
  135. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  136. data/lib/active_support/core_ext/time/conversions.rb +4 -0
  137. data/lib/active_support/core_ext/time/zones.rb +6 -4
  138. data/lib/active_support/core_ext/time.rb +2 -0
  139. data/lib/active_support/core_ext/uri.rb +11 -6
  140. data/lib/active_support/core_ext.rb +3 -1
  141. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  142. data/lib/active_support/current_attributes.rb +210 -0
  143. data/lib/active_support/dependencies/autoload.rb +2 -0
  144. data/lib/active_support/dependencies/interlock.rb +2 -0
  145. data/lib/active_support/dependencies/zeitwerk_integration.rb +120 -0
  146. data/lib/active_support/dependencies.rb +134 -60
  147. data/lib/active_support/deprecation/behaviors.rb +43 -11
  148. data/lib/active_support/deprecation/constant_accessor.rb +4 -2
  149. data/lib/active_support/deprecation/disallowed.rb +56 -0
  150. data/lib/active_support/deprecation/instance_delegator.rb +2 -1
  151. data/lib/active_support/deprecation/method_wrappers.rb +29 -21
  152. data/lib/active_support/deprecation/proxy_wrappers.rb +32 -6
  153. data/lib/active_support/deprecation/reporting.rb +54 -9
  154. data/lib/active_support/deprecation.rb +9 -2
  155. data/lib/active_support/descendants_tracker.rb +61 -9
  156. data/lib/active_support/digest.rb +22 -0
  157. data/lib/active_support/duration/iso8601_parser.rb +6 -6
  158. data/lib/active_support/duration/iso8601_serializer.rb +20 -14
  159. data/lib/active_support/duration.rb +102 -45
  160. data/lib/active_support/encrypted_configuration.rb +45 -0
  161. data/lib/active_support/encrypted_file.rb +117 -0
  162. data/lib/active_support/environment_inquirer.rb +20 -0
  163. data/lib/active_support/evented_file_update_checker.rb +84 -117
  164. data/lib/active_support/execution_wrapper.rb +19 -13
  165. data/lib/active_support/executor.rb +2 -0
  166. data/lib/active_support/file_update_checker.rb +2 -1
  167. data/lib/active_support/fork_tracker.rb +64 -0
  168. data/lib/active_support/gem_version.rb +3 -1
  169. data/lib/active_support/gzip.rb +2 -0
  170. data/lib/active_support/hash_with_indifferent_access.rb +123 -41
  171. data/lib/active_support/i18n.rb +4 -1
  172. data/lib/active_support/i18n_railtie.rb +19 -14
  173. data/lib/active_support/inflections.rb +2 -0
  174. data/lib/active_support/inflector/inflections.rb +19 -8
  175. data/lib/active_support/inflector/methods.rb +87 -77
  176. data/lib/active_support/inflector/transliterate.rb +56 -18
  177. data/lib/active_support/inflector.rb +2 -0
  178. data/lib/active_support/json/decoding.rb +27 -26
  179. data/lib/active_support/json/encoding.rb +13 -3
  180. data/lib/active_support/json.rb +2 -0
  181. data/lib/active_support/key_generator.rb +3 -33
  182. data/lib/active_support/lazy_load_hooks.rb +7 -2
  183. data/lib/active_support/locale/en.rb +33 -0
  184. data/lib/active_support/locale/en.yml +7 -3
  185. data/lib/active_support/log_subscriber/test_helper.rb +2 -0
  186. data/lib/active_support/log_subscriber.rb +42 -11
  187. data/lib/active_support/logger.rb +4 -17
  188. data/lib/active_support/logger_silence.rb +13 -20
  189. data/lib/active_support/logger_thread_safe_level.rb +54 -7
  190. data/lib/active_support/message_encryptor.rb +100 -32
  191. data/lib/active_support/message_verifier.rb +85 -14
  192. data/lib/active_support/messages/metadata.rb +80 -0
  193. data/lib/active_support/messages/rotation_configuration.rb +23 -0
  194. data/lib/active_support/messages/rotator.rb +57 -0
  195. data/lib/active_support/multibyte/chars.rb +12 -68
  196. data/lib/active_support/multibyte/unicode.rb +17 -327
  197. data/lib/active_support/multibyte.rb +2 -0
  198. data/lib/active_support/notifications/fanout.rb +118 -16
  199. data/lib/active_support/notifications/instrumenter.rb +73 -9
  200. data/lib/active_support/notifications.rb +74 -8
  201. data/lib/active_support/number_helper/number_converter.rb +7 -6
  202. data/lib/active_support/number_helper/number_to_currency_converter.rb +6 -9
  203. data/lib/active_support/number_helper/number_to_delimited_converter.rb +5 -2
  204. data/lib/active_support/number_helper/number_to_human_converter.rb +6 -3
  205. data/lib/active_support/number_helper/number_to_human_size_converter.rb +6 -3
  206. data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
  207. data/lib/active_support/number_helper/number_to_phone_converter.rb +5 -2
  208. data/lib/active_support/number_helper/number_to_rounded_converter.rb +14 -27
  209. data/lib/active_support/number_helper/rounding_helper.rb +16 -30
  210. data/lib/active_support/number_helper.rb +40 -12
  211. data/lib/active_support/option_merger.rb +24 -3
  212. data/lib/active_support/ordered_hash.rb +3 -1
  213. data/lib/active_support/ordered_options.rb +17 -5
  214. data/lib/active_support/parameter_filter.rb +133 -0
  215. data/lib/active_support/per_thread_registry.rb +4 -1
  216. data/lib/active_support/proxy_object.rb +2 -0
  217. data/lib/active_support/rails.rb +3 -10
  218. data/lib/active_support/railtie.rb +60 -9
  219. data/lib/active_support/reloader.rb +12 -11
  220. data/lib/active_support/rescuable.rb +7 -6
  221. data/lib/active_support/secure_compare_rotator.rb +51 -0
  222. data/lib/active_support/security_utils.rb +26 -15
  223. data/lib/active_support/string_inquirer.rb +6 -3
  224. data/lib/active_support/subscriber.rb +74 -24
  225. data/lib/active_support/tagged_logging.rb +44 -8
  226. data/lib/active_support/test_case.rb +94 -2
  227. data/lib/active_support/testing/assertions.rb +58 -20
  228. data/lib/active_support/testing/autorun.rb +2 -0
  229. data/lib/active_support/testing/constant_lookup.rb +2 -0
  230. data/lib/active_support/testing/declarative.rb +2 -0
  231. data/lib/active_support/testing/deprecation.rb +2 -1
  232. data/lib/active_support/testing/file_fixtures.rb +4 -0
  233. data/lib/active_support/testing/isolation.rb +4 -2
  234. data/lib/active_support/testing/method_call_assertions.rb +30 -1
  235. data/lib/active_support/testing/parallelization/server.rb +78 -0
  236. data/lib/active_support/testing/parallelization/worker.rb +100 -0
  237. data/lib/active_support/testing/parallelization.rb +51 -0
  238. data/lib/active_support/testing/setup_and_teardown.rb +12 -7
  239. data/lib/active_support/testing/stream.rb +3 -2
  240. data/lib/active_support/testing/tagged_logging.rb +2 -0
  241. data/lib/active_support/testing/time_helpers.rb +78 -13
  242. data/lib/active_support/time.rb +2 -0
  243. data/lib/active_support/time_with_zone.rb +113 -41
  244. data/lib/active_support/values/time_zone.rb +54 -25
  245. data/lib/active_support/version.rb +2 -0
  246. data/lib/active_support/xml_mini/jdom.rb +5 -4
  247. data/lib/active_support/xml_mini/libxml.rb +4 -2
  248. data/lib/active_support/xml_mini/libxmlsax.rb +6 -4
  249. data/lib/active_support/xml_mini/nokogiri.rb +4 -2
  250. data/lib/active_support/xml_mini/nokogirisax.rb +5 -3
  251. data/lib/active_support/xml_mini/rexml.rb +12 -3
  252. data/lib/active_support/xml_mini.rb +5 -11
  253. data/lib/active_support.rb +18 -13
  254. metadata +71 -32
  255. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
  256. data/lib/active_support/core_ext/hash/compact.rb +0 -27
  257. data/lib/active_support/core_ext/hash/transform_values.rb +0 -30
  258. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  259. data/lib/active_support/core_ext/module/reachable.rb +0 -8
  260. data/lib/active_support/core_ext/numeric/inquiry.rb +0 -26
  261. data/lib/active_support/core_ext/range/include_range.rb +0 -23
  262. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,9 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/duration"
2
4
  require "active_support/core_ext/time/conversions"
3
5
  require "active_support/time_with_zone"
4
6
  require "active_support/core_ext/time/zones"
5
7
  require "active_support/core_ext/date_and_time/calculations"
6
8
  require "active_support/core_ext/date/calculations"
9
+ require "active_support/core_ext/module/remove_method"
7
10
 
8
11
  class Time
9
12
  include DateAndTime::Calculations
@@ -45,12 +48,15 @@ class Time
45
48
  # Time.at can be called with a time or numerical value
46
49
  time_or_number = args.first
47
50
 
48
- if time_or_number.is_a?(ActiveSupport::TimeWithZone) || time_or_number.is_a?(DateTime)
51
+ if time_or_number.is_a?(ActiveSupport::TimeWithZone)
52
+ at_without_coercion(time_or_number.to_r).getlocal
53
+ elsif time_or_number.is_a?(DateTime)
49
54
  at_without_coercion(time_or_number.to_f).getlocal
50
55
  else
51
56
  at_without_coercion(time_or_number)
52
57
  end
53
58
  end
59
+ ruby2_keywords(:at_with_coercion) if respond_to?(:ruby2_keywords, true)
54
60
  alias_method :at_without_coercion, :at
55
61
  alias_method :at, :at_with_coercion
56
62
 
@@ -103,25 +109,41 @@ class Time
103
109
  subsec
104
110
  end
105
111
 
112
+ unless Time.method_defined?(:floor)
113
+ def floor(precision = 0)
114
+ change(nsec: 0) + subsec.floor(precision)
115
+ end
116
+ end
117
+
118
+ # Restricted Ruby version due to a bug in `Time#ceil`
119
+ # See https://bugs.ruby-lang.org/issues/17025 for more details
120
+ if RUBY_VERSION <= "2.8"
121
+ remove_possible_method :ceil
122
+ def ceil(precision = 0)
123
+ change(nsec: 0) + subsec.ceil(precision)
124
+ end
125
+ end
126
+
106
127
  # Returns a new Time where one or more of the elements have been changed according
107
128
  # to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
108
129
  # <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
109
130
  # the hour is passed, then minute, sec, usec and nsec is set to 0. If the hour
110
- # and minute is passed, then sec, usec and nsec is set to 0. The +options+
111
- # parameter takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>,
112
- # <tt>:day</tt>, <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>
113
- # <tt>:nsec</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
131
+ # and minute is passed, then sec, usec and nsec is set to 0. The +options+ parameter
132
+ # takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>,
133
+ # <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>,
134
+ # <tt>:offset</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
114
135
  #
115
136
  # Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0)
116
137
  # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0)
117
138
  # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => Time.new(1981, 8, 29, 0, 0, 0)
118
139
  def change(options)
119
- new_year = options.fetch(:year, year)
120
- new_month = options.fetch(:month, month)
121
- new_day = options.fetch(:day, day)
122
- new_hour = options.fetch(:hour, hour)
123
- new_min = options.fetch(:min, options[:hour] ? 0 : min)
124
- new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
140
+ new_year = options.fetch(:year, year)
141
+ new_month = options.fetch(:month, month)
142
+ new_day = options.fetch(:day, day)
143
+ new_hour = options.fetch(:hour, hour)
144
+ new_min = options.fetch(:min, options[:hour] ? 0 : min)
145
+ new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
146
+ new_offset = options.fetch(:offset, nil)
125
147
 
126
148
  if new_nsec = options[:nsec]
127
149
  raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec]
@@ -130,13 +152,20 @@ class Time
130
152
  new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
131
153
  end
132
154
 
133
- if utc?
134
- ::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec)
155
+ raise ArgumentError, "argument out of range" if new_usec >= 1000000
156
+
157
+ new_sec += Rational(new_usec, 1000000)
158
+
159
+ if new_offset
160
+ ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, new_offset)
161
+ elsif utc?
162
+ ::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec)
163
+ elsif zone&.respond_to?(:utc_to_local)
164
+ ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, zone)
135
165
  elsif zone
136
- ::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec)
166
+ ::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec)
137
167
  else
138
- raise ArgumentError, "argument out of range" if new_usec >= 1000000
139
- ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec + (new_usec.to_r / 1000000), utc_offset)
168
+ ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, utc_offset)
140
169
  end
141
170
  end
142
171
 
@@ -162,8 +191,7 @@ class Time
162
191
  options[:hours] = options.fetch(:hours, 0) + 24 * partial_days
163
192
  end
164
193
 
165
- d = to_date.advance(options)
166
- d = d.gregorian if d.julian?
194
+ d = to_date.gregorian.advance(options)
167
195
  time_advanced_by_date = change(year: d.year, month: d.month, day: d.day)
168
196
  seconds_to_advance = \
169
197
  options.fetch(:seconds, 0) +
@@ -304,4 +332,34 @@ class Time
304
332
  end
305
333
  alias_method :eql_without_coercion, :eql?
306
334
  alias_method :eql?, :eql_with_coercion
335
+
336
+ # Returns a new time the specified number of days ago.
337
+ def prev_day(days = 1)
338
+ advance(days: -days)
339
+ end
340
+
341
+ # Returns a new time the specified number of days in the future.
342
+ def next_day(days = 1)
343
+ advance(days: days)
344
+ end
345
+
346
+ # Returns a new time the specified number of months ago.
347
+ def prev_month(months = 1)
348
+ advance(months: -months)
349
+ end
350
+
351
+ # Returns a new time the specified number of months in the future.
352
+ def next_month(months = 1)
353
+ advance(months: months)
354
+ end
355
+
356
+ # Returns a new time the specified number of years ago.
357
+ def prev_year(years = 1)
358
+ advance(years: -years)
359
+ end
360
+
361
+ # Returns a new time the specified number of years in the future.
362
+ def next_year(years = 1)
363
+ advance(years: years)
364
+ end
307
365
  end
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/date_and_time/compatibility"
2
- require "active_support/core_ext/module/remove_method"
4
+ require "active_support/core_ext/module/redefine_method"
3
5
 
4
6
  class Time
5
7
  include DateAndTime::Compatibility
6
8
 
7
- remove_possible_method :to_time
9
+ silence_redefinition_of_method :to_time
8
10
 
9
11
  # Either return +self+ or the time in the local system timezone depending
10
12
  # on the setting of +ActiveSupport.to_time_preserves_timezone+.
@@ -1,9 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "time"
1
4
  require "active_support/inflector/methods"
2
5
  require "active_support/values/time_zone"
3
6
 
4
7
  class Time
5
8
  DATE_FORMATS = {
6
9
  db: "%Y-%m-%d %H:%M:%S",
10
+ inspect: "%Y-%m-%d %H:%M:%S.%9N %z",
7
11
  number: "%Y%m%d%H%M%S",
8
12
  nsec: "%Y%m%d%H%M%S%9N",
9
13
  usec: "%Y%m%d%H%M%S%6N",
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/time_with_zone"
2
4
  require "active_support/core_ext/time/acts_like"
3
5
  require "active_support/core_ext/date_and_time/zones"
@@ -53,10 +55,10 @@ class Time
53
55
  # end
54
56
  # end
55
57
  #
56
- # NOTE: This won't affect any <tt>ActiveSupport::TimeWithZone</tt>
57
- # objects that have already been created, e.g. any model timestamp
58
- # attributes that have been read before the block will remain in
59
- # the application's default timezone.
58
+ # NOTE: This won't affect any <tt>ActiveSupport::TimeWithZone</tt>
59
+ # objects that have already been created, e.g. any model timestamp
60
+ # attributes that have been read before the block will remain in
61
+ # the application's default timezone.
60
62
  def use_zone(time_zone)
61
63
  new_zone = find_zone!(time_zone)
62
64
  begin
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/time/acts_like"
2
4
  require "active_support/core_ext/time/calculations"
3
5
  require "active_support/core_ext/time/compatibility"
@@ -1,16 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "uri"
2
- str = "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E" # Ni-ho-nn-go in UTF-8, means Japanese.
3
- parser = URI::Parser.new
4
4
 
5
- unless str == parser.unescape(parser.escape(str))
5
+ if RUBY_VERSION < "2.6.0"
6
+ require "active_support/core_ext/module/redefine_method"
6
7
  URI::Parser.class_eval do
7
- remove_method :unescape
8
+ silence_redefinition_of_method :unescape
8
9
  def unescape(str, escaped = /%[a-fA-F\d]{2}/)
9
10
  # TODO: Are we actually sure that ASCII == UTF-8?
10
11
  # YK: My initial experiments say yes, but let's be sure please
11
12
  enc = str.encoding
12
13
  enc = Encoding::UTF_8 if enc == Encoding::US_ASCII
13
- str.gsub(escaped) { |match| [match[1, 2].hex].pack("C") }.force_encoding(enc)
14
+ str.dup.force_encoding(Encoding::ASCII_8BIT).gsub(escaped) { |match| [match[1, 2].hex].pack("C") }.force_encoding(enc)
14
15
  end
15
16
  end
16
17
  end
@@ -18,7 +19,11 @@ end
18
19
  module URI
19
20
  class << self
20
21
  def parser
21
- @parser ||= URI::Parser.new
22
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
23
+ URI.parser is deprecated and will be removed in Rails 7.0.
24
+ Use `URI::DEFAULT_PARSER` instead.
25
+ MSG
26
+ URI::DEFAULT_PARSER
22
27
  end
23
28
  end
24
29
  end
@@ -1,3 +1,5 @@
1
- (Dir["#{File.dirname(__FILE__)}/core_ext/*.rb"]).each do |path|
1
+ # frozen_string_literal: true
2
+
3
+ Dir.glob(File.expand_path("core_ext/*.rb", __dir__)).sort.each do |path|
2
4
  require path
3
5
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport::CurrentAttributes::TestHelper # :nodoc:
4
+ def before_setup
5
+ ActiveSupport::CurrentAttributes.reset_all
6
+ super
7
+ end
8
+
9
+ def after_teardown
10
+ super
11
+ ActiveSupport::CurrentAttributes.reset_all
12
+ end
13
+ end
@@ -0,0 +1,210 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/callbacks"
4
+ require "active_support/core_ext/enumerable"
5
+ require "active_support/core_ext/module/delegation"
6
+
7
+ module ActiveSupport
8
+ # Abstract super class that provides a thread-isolated attributes singleton, which resets automatically
9
+ # before and after each request. This allows you to keep all the per-request attributes easily
10
+ # available to the whole system.
11
+ #
12
+ # The following full app-like example demonstrates how to use a Current class to
13
+ # facilitate easy access to the global, per-request attributes without passing them deeply
14
+ # around everywhere:
15
+ #
16
+ # # app/models/current.rb
17
+ # class Current < ActiveSupport::CurrentAttributes
18
+ # attribute :account, :user
19
+ # attribute :request_id, :user_agent, :ip_address
20
+ #
21
+ # resets { Time.zone = nil }
22
+ #
23
+ # def user=(user)
24
+ # super
25
+ # self.account = user.account
26
+ # Time.zone = user.time_zone
27
+ # end
28
+ # end
29
+ #
30
+ # # app/controllers/concerns/authentication.rb
31
+ # module Authentication
32
+ # extend ActiveSupport::Concern
33
+ #
34
+ # included do
35
+ # before_action :authenticate
36
+ # end
37
+ #
38
+ # private
39
+ # def authenticate
40
+ # if authenticated_user = User.find_by(id: cookies.encrypted[:user_id])
41
+ # Current.user = authenticated_user
42
+ # else
43
+ # redirect_to new_session_url
44
+ # end
45
+ # end
46
+ # end
47
+ #
48
+ # # app/controllers/concerns/set_current_request_details.rb
49
+ # module SetCurrentRequestDetails
50
+ # extend ActiveSupport::Concern
51
+ #
52
+ # included do
53
+ # before_action do
54
+ # Current.request_id = request.uuid
55
+ # Current.user_agent = request.user_agent
56
+ # Current.ip_address = request.ip
57
+ # end
58
+ # end
59
+ # end
60
+ #
61
+ # class ApplicationController < ActionController::Base
62
+ # include Authentication
63
+ # include SetCurrentRequestDetails
64
+ # end
65
+ #
66
+ # class MessagesController < ApplicationController
67
+ # def create
68
+ # Current.account.messages.create(message_params)
69
+ # end
70
+ # end
71
+ #
72
+ # class Message < ApplicationRecord
73
+ # belongs_to :creator, default: -> { Current.user }
74
+ # after_create { |message| Event.create(record: message) }
75
+ # end
76
+ #
77
+ # class Event < ApplicationRecord
78
+ # before_create do
79
+ # self.request_id = Current.request_id
80
+ # self.user_agent = Current.user_agent
81
+ # self.ip_address = Current.ip_address
82
+ # end
83
+ # end
84
+ #
85
+ # A word of caution: It's easy to overdo a global singleton like Current and tangle your model as a result.
86
+ # Current should only be used for a few, top-level globals, like account, user, and request details.
87
+ # The attributes stuck in Current should be used by more or less all actions on all requests. If you start
88
+ # sticking controller-specific attributes in there, you're going to create a mess.
89
+ class CurrentAttributes
90
+ include ActiveSupport::Callbacks
91
+ define_callbacks :reset
92
+
93
+ class << self
94
+ # Returns singleton instance for this class in this thread. If none exists, one is created.
95
+ def instance
96
+ current_instances[current_instances_key] ||= new
97
+ end
98
+
99
+ # Declares one or more attributes that will be given both class and instance accessor methods.
100
+ def attribute(*names)
101
+ generated_attribute_methods.module_eval do
102
+ names.each do |name|
103
+ define_method(name) do
104
+ attributes[name.to_sym]
105
+ end
106
+
107
+ define_method("#{name}=") do |attribute|
108
+ attributes[name.to_sym] = attribute
109
+ end
110
+ end
111
+ end
112
+
113
+ names.each do |name|
114
+ define_singleton_method(name) do
115
+ instance.public_send(name)
116
+ end
117
+
118
+ define_singleton_method("#{name}=") do |attribute|
119
+ instance.public_send("#{name}=", attribute)
120
+ end
121
+ end
122
+ end
123
+
124
+ # Calls this block before #reset is called on the instance. Used for resetting external collaborators that depend on current values.
125
+ def before_reset(&block)
126
+ set_callback :reset, :before, &block
127
+ end
128
+
129
+ # Calls this block after #reset is called on the instance. Used for resetting external collaborators, like Time.zone.
130
+ def resets(&block)
131
+ set_callback :reset, :after, &block
132
+ end
133
+ alias_method :after_reset, :resets
134
+
135
+ delegate :set, :reset, to: :instance
136
+
137
+ def reset_all # :nodoc:
138
+ current_instances.each_value(&:reset)
139
+ end
140
+
141
+ def clear_all # :nodoc:
142
+ reset_all
143
+ current_instances.clear
144
+ end
145
+
146
+ private
147
+ def generated_attribute_methods
148
+ @generated_attribute_methods ||= Module.new.tap { |mod| include mod }
149
+ end
150
+
151
+ def current_instances
152
+ Thread.current[:current_attributes_instances] ||= {}
153
+ end
154
+
155
+ def current_instances_key
156
+ @current_instances_key ||= name.to_sym
157
+ end
158
+
159
+ def method_missing(name, *args, &block)
160
+ # Caches the method definition as a singleton method of the receiver.
161
+ #
162
+ # By letting #delegate handle it, we avoid an enclosure that'll capture args.
163
+ singleton_class.delegate name, to: :instance
164
+
165
+ send(name, *args, &block)
166
+ end
167
+ ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
168
+ end
169
+
170
+ attr_accessor :attributes
171
+
172
+ def initialize
173
+ @attributes = {}
174
+ end
175
+
176
+ # Expose one or more attributes within a block. Old values are returned after the block concludes.
177
+ # Example demonstrating the common use of needing to set Current attributes outside the request-cycle:
178
+ #
179
+ # class Chat::PublicationJob < ApplicationJob
180
+ # def perform(attributes, room_number, creator)
181
+ # Current.set(person: creator) do
182
+ # Chat::Publisher.publish(attributes: attributes, room_number: room_number)
183
+ # end
184
+ # end
185
+ # end
186
+ def set(set_attributes)
187
+ old_attributes = compute_attributes(set_attributes.keys)
188
+ assign_attributes(set_attributes)
189
+ yield
190
+ ensure
191
+ assign_attributes(old_attributes)
192
+ end
193
+
194
+ # Reset all attributes. Should be called before and after actions, when used as a per-request singleton.
195
+ def reset
196
+ run_callbacks :reset do
197
+ self.attributes = {}
198
+ end
199
+ end
200
+
201
+ private
202
+ def assign_attributes(new_attributes)
203
+ new_attributes.each { |key, value| public_send("#{key}=", value) }
204
+ end
205
+
206
+ def compute_attributes(keys)
207
+ keys.index_with { |key| public_send(key) }
208
+ end
209
+ end
210
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/inflector/methods"
2
4
 
3
5
  module ActiveSupport
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/concurrency/share_lock"
2
4
 
3
5
  module ActiveSupport #:nodoc:
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "set"
4
+ require "active_support/core_ext/string/inflections"
5
+
6
+ module ActiveSupport
7
+ module Dependencies
8
+ module ZeitwerkIntegration # :nodoc: all
9
+ module Decorations
10
+ def clear
11
+ Dependencies.unload_interlock do
12
+ Rails.autoloaders.main.reload
13
+ rescue Zeitwerk::ReloadingDisabledError
14
+ raise "reloading is disabled because config.cache_classes is true"
15
+ end
16
+ end
17
+
18
+ def constantize(cpath)
19
+ ActiveSupport::Inflector.constantize(cpath)
20
+ end
21
+
22
+ def safe_constantize(cpath)
23
+ ActiveSupport::Inflector.safe_constantize(cpath)
24
+ end
25
+
26
+ def autoloaded_constants
27
+ Rails.autoloaders.main.unloadable_cpaths
28
+ end
29
+
30
+ def autoloaded?(object)
31
+ cpath = object.is_a?(Module) ? real_mod_name(object) : object.to_s
32
+ Rails.autoloaders.main.unloadable_cpath?(cpath)
33
+ end
34
+
35
+ def verbose=(verbose)
36
+ l = verbose ? logger || Rails.logger : nil
37
+ Rails.autoloaders.each { |autoloader| autoloader.logger = l }
38
+ end
39
+
40
+ def unhook!
41
+ :no_op
42
+ end
43
+ end
44
+
45
+ module RequireDependency
46
+ def require_dependency(filename)
47
+ filename = filename.to_path if filename.respond_to?(:to_path)
48
+ if abspath = ActiveSupport::Dependencies.search_for_file(filename)
49
+ require abspath
50
+ else
51
+ require filename
52
+ end
53
+ end
54
+ end
55
+
56
+ module Inflector
57
+ # Concurrent::Map is not needed. This is a private class, and overrides
58
+ # must be defined while the application boots.
59
+ @overrides = {}
60
+
61
+ def self.camelize(basename, _abspath)
62
+ @overrides[basename] || basename.camelize
63
+ end
64
+
65
+ def self.inflect(overrides)
66
+ @overrides.merge!(overrides)
67
+ end
68
+ end
69
+
70
+ class << self
71
+ def take_over(enable_reloading:)
72
+ setup_autoloaders(enable_reloading)
73
+ freeze_paths
74
+ decorate_dependencies
75
+ end
76
+
77
+ private
78
+ def setup_autoloaders(enable_reloading)
79
+ Dependencies.autoload_paths.each do |autoload_path|
80
+ # Zeitwerk only accepts existing directories in `push_dir` to
81
+ # prevent misconfigurations.
82
+ next unless File.directory?(autoload_path)
83
+
84
+ autoloader = \
85
+ autoload_once?(autoload_path) ? Rails.autoloaders.once : Rails.autoloaders.main
86
+
87
+ autoloader.push_dir(autoload_path)
88
+ autoloader.do_not_eager_load(autoload_path) unless eager_load?(autoload_path)
89
+ end
90
+
91
+ Rails.autoloaders.main.enable_reloading if enable_reloading
92
+
93
+ # Order matters.
94
+ Rails.autoloaders.once.setup
95
+ Rails.autoloaders.main.setup
96
+ end
97
+
98
+ def autoload_once?(autoload_path)
99
+ Dependencies.autoload_once_paths.include?(autoload_path)
100
+ end
101
+
102
+ def eager_load?(autoload_path)
103
+ Dependencies._eager_load_paths.member?(autoload_path)
104
+ end
105
+
106
+ def freeze_paths
107
+ Dependencies.autoload_paths.freeze
108
+ Dependencies.autoload_once_paths.freeze
109
+ Dependencies._eager_load_paths.freeze
110
+ end
111
+
112
+ def decorate_dependencies
113
+ Dependencies.unhook!
114
+ Dependencies.singleton_class.prepend(Decorations)
115
+ Object.prepend(RequireDependency)
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end