activesupport 5.1.6 → 5.2.0

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 (240) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +325 -576
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +3 -3
  5. data/lib/active_support/all.rb +2 -0
  6. data/lib/active_support/array_inquirer.rb +2 -0
  7. data/lib/active_support/backtrace_cleaner.rb +2 -0
  8. data/lib/active_support/benchmarkable.rb +2 -0
  9. data/lib/active_support/builder.rb +2 -0
  10. data/lib/active_support/cache/file_store.rb +5 -4
  11. data/lib/active_support/cache/mem_cache_store.rb +37 -27
  12. data/lib/active_support/cache/memory_store.rb +2 -0
  13. data/lib/active_support/cache/null_store.rb +2 -0
  14. data/lib/active_support/cache/redis_cache_store.rb +454 -0
  15. data/lib/active_support/cache/strategy/local_cache.rb +33 -2
  16. data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
  17. data/lib/active_support/cache.rb +181 -64
  18. data/lib/active_support/callbacks.rb +28 -39
  19. data/lib/active_support/concern.rb +3 -1
  20. data/lib/active_support/concurrency/share_lock.rb +2 -0
  21. data/lib/active_support/configurable.rb +2 -0
  22. data/lib/active_support/core_ext/array/access.rb +4 -2
  23. data/lib/active_support/core_ext/array/conversions.rb +2 -0
  24. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  25. data/lib/active_support/core_ext/array/grouping.rb +2 -0
  26. data/lib/active_support/core_ext/array/inquiry.rb +2 -0
  27. data/lib/active_support/core_ext/array/prepend_and_append.rb +4 -2
  28. data/lib/active_support/core_ext/array/wrap.rb +2 -0
  29. data/lib/active_support/core_ext/array.rb +2 -0
  30. data/lib/active_support/core_ext/benchmark.rb +2 -0
  31. data/lib/active_support/core_ext/big_decimal/conversions.rb +2 -0
  32. data/lib/active_support/core_ext/big_decimal.rb +2 -0
  33. data/lib/active_support/core_ext/class/attribute.rb +34 -16
  34. data/lib/active_support/core_ext/class/attribute_accessors.rb +2 -0
  35. data/lib/active_support/core_ext/class/subclasses.rb +1 -2
  36. data/lib/active_support/core_ext/class.rb +2 -0
  37. data/lib/active_support/core_ext/date/acts_like.rb +2 -0
  38. data/lib/active_support/core_ext/date/blank.rb +2 -0
  39. data/lib/active_support/core_ext/date/calculations.rb +2 -0
  40. data/lib/active_support/core_ext/date/conversions.rb +10 -9
  41. data/lib/active_support/core_ext/date/zones.rb +2 -0
  42. data/lib/active_support/core_ext/date.rb +2 -0
  43. data/lib/active_support/core_ext/date_and_time/calculations.rb +50 -16
  44. data/lib/active_support/core_ext/date_and_time/compatibility.rb +3 -1
  45. data/lib/active_support/core_ext/date_and_time/zones.rb +2 -0
  46. data/lib/active_support/core_ext/date_time/acts_like.rb +2 -0
  47. data/lib/active_support/core_ext/date_time/blank.rb +2 -0
  48. data/lib/active_support/core_ext/date_time/calculations.rb +2 -0
  49. data/lib/active_support/core_ext/date_time/compatibility.rb +7 -5
  50. data/lib/active_support/core_ext/date_time/conversions.rb +2 -0
  51. data/lib/active_support/core_ext/date_time.rb +2 -0
  52. data/lib/active_support/core_ext/digest/uuid.rb +3 -1
  53. data/lib/active_support/core_ext/enumerable.rb +3 -1
  54. data/lib/active_support/core_ext/file/atomic.rb +2 -0
  55. data/lib/active_support/core_ext/file.rb +2 -0
  56. data/lib/active_support/core_ext/hash/compact.rb +2 -0
  57. data/lib/active_support/core_ext/hash/conversions.rb +4 -2
  58. data/lib/active_support/core_ext/hash/deep_merge.rb +8 -12
  59. data/lib/active_support/core_ext/hash/except.rb +2 -0
  60. data/lib/active_support/core_ext/hash/indifferent_access.rb +2 -0
  61. data/lib/active_support/core_ext/hash/keys.rb +2 -0
  62. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  63. data/lib/active_support/core_ext/hash/slice.rb +4 -4
  64. data/lib/active_support/core_ext/hash/transform_values.rb +2 -0
  65. data/lib/active_support/core_ext/hash.rb +2 -0
  66. data/lib/active_support/core_ext/integer/inflections.rb +2 -0
  67. data/lib/active_support/core_ext/integer/multiple.rb +2 -0
  68. data/lib/active_support/core_ext/integer/time.rb +7 -14
  69. data/lib/active_support/core_ext/integer.rb +2 -0
  70. data/lib/active_support/core_ext/kernel/agnostics.rb +2 -0
  71. data/lib/active_support/core_ext/kernel/concern.rb +2 -0
  72. data/lib/active_support/core_ext/kernel/reporting.rb +2 -0
  73. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  74. data/lib/active_support/core_ext/kernel.rb +2 -0
  75. data/lib/active_support/core_ext/load_error.rb +2 -7
  76. data/lib/active_support/core_ext/marshal.rb +2 -0
  77. data/lib/active_support/core_ext/module/aliasing.rb +2 -0
  78. data/lib/active_support/core_ext/module/anonymous.rb +2 -0
  79. data/lib/active_support/core_ext/module/attr_internal.rb +2 -0
  80. data/lib/active_support/core_ext/module/attribute_accessors.rb +21 -24
  81. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +2 -0
  82. data/lib/active_support/core_ext/module/concerning.rb +7 -8
  83. data/lib/active_support/core_ext/module/delegation.rb +31 -29
  84. data/lib/active_support/core_ext/module/deprecation.rb +2 -0
  85. data/lib/active_support/core_ext/module/introspection.rb +2 -0
  86. data/lib/active_support/core_ext/module/reachable.rb +3 -0
  87. data/lib/active_support/core_ext/module/redefine_method.rb +49 -0
  88. data/lib/active_support/core_ext/module/remove_method.rb +5 -23
  89. data/lib/active_support/core_ext/module.rb +3 -0
  90. data/lib/active_support/core_ext/name_error.rb +7 -0
  91. data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
  92. data/lib/active_support/core_ext/numeric/conversions.rb +9 -7
  93. data/lib/active_support/core_ext/numeric/inquiry.rb +2 -0
  94. data/lib/active_support/core_ext/numeric/time.rb +7 -15
  95. data/lib/active_support/core_ext/numeric.rb +2 -0
  96. data/lib/active_support/core_ext/object/acts_like.rb +12 -1
  97. data/lib/active_support/core_ext/object/blank.rb +12 -1
  98. data/lib/active_support/core_ext/object/conversions.rb +2 -0
  99. data/lib/active_support/core_ext/object/deep_dup.rb +2 -0
  100. data/lib/active_support/core_ext/object/duplicable.rb +10 -8
  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 +8 -0
  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 +2 -0
  107. data/lib/active_support/core_ext/object/with_options.rb +3 -1
  108. data/lib/active_support/core_ext/object.rb +2 -0
  109. data/lib/active_support/core_ext/range/conversions.rb +9 -1
  110. data/lib/active_support/core_ext/range/each.rb +5 -1
  111. data/lib/active_support/core_ext/range/include_range.rb +2 -0
  112. data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
  113. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  114. data/lib/active_support/core_ext/range.rb +3 -0
  115. data/lib/active_support/core_ext/regexp.rb +2 -0
  116. data/lib/active_support/core_ext/securerandom.rb +2 -0
  117. data/lib/active_support/core_ext/string/access.rb +2 -0
  118. data/lib/active_support/core_ext/string/behavior.rb +2 -0
  119. data/lib/active_support/core_ext/string/conversions.rb +2 -0
  120. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  121. data/lib/active_support/core_ext/string/filters.rb +2 -0
  122. data/lib/active_support/core_ext/string/indent.rb +2 -0
  123. data/lib/active_support/core_ext/string/inflections.rb +26 -12
  124. data/lib/active_support/core_ext/string/inquiry.rb +2 -0
  125. data/lib/active_support/core_ext/string/multibyte.rb +4 -0
  126. data/lib/active_support/core_ext/string/output_safety.rb +6 -7
  127. data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
  128. data/lib/active_support/core_ext/string/strip.rb +2 -0
  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/time/acts_like.rb +2 -0
  132. data/lib/active_support/core_ext/time/calculations.rb +23 -15
  133. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  134. data/lib/active_support/core_ext/time/conversions.rb +2 -0
  135. data/lib/active_support/core_ext/time/zones.rb +6 -4
  136. data/lib/active_support/core_ext/time.rb +2 -0
  137. data/lib/active_support/core_ext/uri.rb +4 -1
  138. data/lib/active_support/core_ext.rb +3 -1
  139. data/lib/active_support/current_attributes.rb +195 -0
  140. data/lib/active_support/dependencies/autoload.rb +2 -0
  141. data/lib/active_support/dependencies/interlock.rb +2 -0
  142. data/lib/active_support/dependencies.rb +16 -25
  143. data/lib/active_support/deprecation/behaviors.rb +24 -9
  144. data/lib/active_support/deprecation/constant_accessor.rb +4 -2
  145. data/lib/active_support/deprecation/instance_delegator.rb +2 -0
  146. data/lib/active_support/deprecation/method_wrappers.rb +8 -8
  147. data/lib/active_support/deprecation/proxy_wrappers.rb +5 -2
  148. data/lib/active_support/deprecation/reporting.rb +5 -3
  149. data/lib/active_support/deprecation.rb +4 -2
  150. data/lib/active_support/descendants_tracker.rb +2 -0
  151. data/lib/active_support/digest.rb +20 -0
  152. data/lib/active_support/duration/iso8601_parser.rb +4 -2
  153. data/lib/active_support/duration/iso8601_serializer.rb +4 -2
  154. data/lib/active_support/duration.rb +11 -7
  155. data/lib/active_support/encrypted_configuration.rb +49 -0
  156. data/lib/active_support/encrypted_file.rb +99 -0
  157. data/lib/active_support/evented_file_update_checker.rb +2 -0
  158. data/lib/active_support/execution_wrapper.rb +2 -0
  159. data/lib/active_support/executor.rb +2 -0
  160. data/lib/active_support/file_update_checker.rb +2 -0
  161. data/lib/active_support/gem_version.rb +4 -2
  162. data/lib/active_support/gzip.rb +2 -0
  163. data/lib/active_support/hash_with_indifferent_access.rb +41 -1
  164. data/lib/active_support/i18n.rb +3 -1
  165. data/lib/active_support/i18n_railtie.rb +4 -6
  166. data/lib/active_support/inflections.rb +2 -0
  167. data/lib/active_support/inflector/inflections.rb +20 -4
  168. data/lib/active_support/inflector/methods.rb +41 -24
  169. data/lib/active_support/inflector/transliterate.rb +17 -8
  170. data/lib/active_support/inflector.rb +2 -0
  171. data/lib/active_support/json/decoding.rb +2 -0
  172. data/lib/active_support/json/encoding.rb +2 -0
  173. data/lib/active_support/json.rb +2 -0
  174. data/lib/active_support/key_generator.rb +3 -1
  175. data/lib/active_support/lazy_load_hooks.rb +2 -0
  176. data/lib/active_support/log_subscriber/test_helper.rb +2 -0
  177. data/lib/active_support/log_subscriber.rb +3 -2
  178. data/lib/active_support/logger.rb +2 -0
  179. data/lib/active_support/logger_silence.rb +3 -2
  180. data/lib/active_support/logger_thread_safe_level.rb +2 -0
  181. data/lib/active_support/message_encryptor.rb +95 -22
  182. data/lib/active_support/message_verifier.rb +78 -7
  183. data/lib/active_support/messages/metadata.rb +71 -0
  184. data/lib/active_support/messages/rotation_configuration.rb +22 -0
  185. data/lib/active_support/messages/rotator.rb +56 -0
  186. data/lib/active_support/multibyte/chars.rb +2 -0
  187. data/lib/active_support/multibyte/unicode.rb +4 -2
  188. data/lib/active_support/multibyte.rb +2 -0
  189. data/lib/active_support/notifications/fanout.rb +2 -0
  190. data/lib/active_support/notifications/instrumenter.rb +2 -0
  191. data/lib/active_support/notifications.rb +2 -0
  192. data/lib/active_support/number_helper/number_converter.rb +2 -0
  193. data/lib/active_support/number_helper/number_to_currency_converter.rb +2 -0
  194. data/lib/active_support/number_helper/number_to_delimited_converter.rb +2 -0
  195. data/lib/active_support/number_helper/number_to_human_converter.rb +2 -0
  196. data/lib/active_support/number_helper/number_to_human_size_converter.rb +2 -0
  197. data/lib/active_support/number_helper/number_to_percentage_converter.rb +2 -0
  198. data/lib/active_support/number_helper/number_to_phone_converter.rb +3 -1
  199. data/lib/active_support/number_helper/number_to_rounded_converter.rb +2 -20
  200. data/lib/active_support/number_helper/rounding_helper.rb +6 -4
  201. data/lib/active_support/number_helper.rb +2 -0
  202. data/lib/active_support/option_merger.rb +2 -0
  203. data/lib/active_support/ordered_hash.rb +2 -0
  204. data/lib/active_support/ordered_options.rb +4 -2
  205. data/lib/active_support/per_thread_registry.rb +2 -0
  206. data/lib/active_support/proxy_object.rb +2 -0
  207. data/lib/active_support/rails.rb +2 -0
  208. data/lib/active_support/railtie.rb +37 -8
  209. data/lib/active_support/reloader.rb +7 -5
  210. data/lib/active_support/rescuable.rb +3 -2
  211. data/lib/active_support/security_utils.rb +15 -11
  212. data/lib/active_support/string_inquirer.rb +2 -0
  213. data/lib/active_support/subscriber.rb +2 -0
  214. data/lib/active_support/tagged_logging.rb +2 -0
  215. data/lib/active_support/test_case.rb +2 -1
  216. data/lib/active_support/testing/assertions.rb +31 -14
  217. data/lib/active_support/testing/autorun.rb +2 -0
  218. data/lib/active_support/testing/constant_lookup.rb +2 -0
  219. data/lib/active_support/testing/declarative.rb +2 -0
  220. data/lib/active_support/testing/deprecation.rb +2 -0
  221. data/lib/active_support/testing/file_fixtures.rb +2 -0
  222. data/lib/active_support/testing/isolation.rb +3 -1
  223. data/lib/active_support/testing/method_call_assertions.rb +2 -0
  224. data/lib/active_support/testing/setup_and_teardown.rb +10 -1
  225. data/lib/active_support/testing/stream.rb +2 -0
  226. data/lib/active_support/testing/tagged_logging.rb +2 -0
  227. data/lib/active_support/testing/time_helpers.rb +33 -3
  228. data/lib/active_support/time.rb +2 -0
  229. data/lib/active_support/time_with_zone.rb +38 -0
  230. data/lib/active_support/values/time_zone.rb +19 -8
  231. data/lib/active_support/version.rb +2 -0
  232. data/lib/active_support/xml_mini/jdom.rb +4 -2
  233. data/lib/active_support/xml_mini/libxml.rb +3 -1
  234. data/lib/active_support/xml_mini/libxmlsax.rb +4 -2
  235. data/lib/active_support/xml_mini/nokogiri.rb +3 -1
  236. data/lib/active_support/xml_mini/nokogirisax.rb +3 -1
  237. data/lib/active_support/xml_mini/rexml.rb +3 -1
  238. data/lib/active_support/xml_mini.rb +3 -1
  239. data/lib/active_support.rb +5 -13
  240. metadata +15 -5
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  module NumberHelper
3
5
  class NumberToRoundedConverter < NumberConverter # :nodoc:
@@ -35,26 +37,6 @@ module ActiveSupport
35
37
 
36
38
  private
37
39
 
38
- def digits_and_rounded_number(precision)
39
- if zero?
40
- [1, 0]
41
- else
42
- digits = digit_count(number)
43
- multiplier = 10**(digits - precision)
44
- rounded_number = calculate_rounded_number(multiplier)
45
- digits = digit_count(rounded_number) # After rounding, the number of digits may have changed
46
- [digits, rounded_number]
47
- end
48
- end
49
-
50
- def calculate_rounded_number(multiplier)
51
- (number / BigDecimal.new(multiplier.to_f.to_s)).round * multiplier
52
- end
53
-
54
- def digit_count(number)
55
- number.zero? ? 1 : (Math.log10(absolute_number(number)) + 1).floor
56
- end
57
-
58
40
  def strip_insignificant_zeros
59
41
  options[:strip_insignificant_zeros]
60
42
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  module NumberHelper
3
5
  class RoundingHelper # :nodoc:
@@ -34,17 +36,17 @@ module ActiveSupport
34
36
  return 0 if number.zero?
35
37
  digits = digit_count(number)
36
38
  multiplier = 10**(digits - precision)
37
- (number / BigDecimal.new(multiplier.to_f.to_s)).round * multiplier
39
+ (number / BigDecimal(multiplier.to_f.to_s)).round * multiplier
38
40
  end
39
41
 
40
42
  def convert_to_decimal(number)
41
43
  case number
42
44
  when Float, String
43
- number = BigDecimal(number.to_s)
45
+ BigDecimal(number.to_s)
44
46
  when Rational
45
- number = BigDecimal(number, digit_count(number.to_i) + precision)
47
+ BigDecimal(number, digit_count(number.to_i) + precision)
46
48
  else
47
- number = number.to_d
49
+ number.to_d
48
50
  end
49
51
  end
50
52
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  module NumberHelper
3
5
  extend ActiveSupport::Autoload
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/hash/deep_merge"
2
4
 
3
5
  module ActiveSupport
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "yaml"
2
4
 
3
5
  YAML.add_builtin_type("omap") do |type, val|
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/object/blank"
2
4
 
3
5
  module ActiveSupport
@@ -22,7 +24,7 @@ module ActiveSupport
22
24
  # To raise an exception when the value is blank, append a
23
25
  # bang to the key name, like:
24
26
  #
25
- # h.dog! # => raises KeyError: key not found: :dog
27
+ # h.dog! # => raises KeyError: :dog is blank
26
28
  #
27
29
  class OrderedOptions < Hash
28
30
  alias_method :_get, :[] # preserve the original #[] method
@@ -44,7 +46,7 @@ module ActiveSupport
44
46
  bangs = name_string.chomp!("!")
45
47
 
46
48
  if bangs
47
- fetch(name_string.to_sym).presence || raise(KeyError.new("#{name_string} is blank."))
49
+ self[name_string].presence || raise(KeyError.new(":#{name_string} is blank"))
48
50
  else
49
51
  self[name_string]
50
52
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/module/delegation"
2
4
 
3
5
  module ActiveSupport
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  # A class with no predefined methods that behaves similarly to Builder's
3
5
  # BlankSlate. Used for proxy classes.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This is private interface.
2
4
  #
3
5
  # Rails components cherry pick from Active Support as needed, but there are a
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support"
2
4
  require "active_support/i18n_railtie"
3
5
 
@@ -7,6 +9,21 @@ module ActiveSupport
7
9
 
8
10
  config.eager_load_namespaces << ActiveSupport
9
11
 
12
+ initializer "active_support.set_authenticated_message_encryption" do |app|
13
+ config.after_initialize do
14
+ unless app.config.active_support.use_authenticated_message_encryption.nil?
15
+ ActiveSupport::MessageEncryptor.use_authenticated_message_encryption =
16
+ app.config.active_support.use_authenticated_message_encryption
17
+ end
18
+ end
19
+ end
20
+
21
+ initializer "active_support.reset_all_current_attributes_instances" do |app|
22
+ app.reloader.before_class_unload { ActiveSupport::CurrentAttributes.clear_all }
23
+ app.executor.to_run { ActiveSupport::CurrentAttributes.reset_all }
24
+ app.executor.to_complete { ActiveSupport::CurrentAttributes.reset_all }
25
+ end
26
+
10
27
  initializer "active_support.deprecation_behavior" do |app|
11
28
  if deprecation = app.config.active_support.deprecation
12
29
  ActiveSupport::Deprecation.behavior = deprecation
@@ -22,14 +39,7 @@ module ActiveSupport
22
39
  raise e.exception "tzinfo-data is not present. Please add gem 'tzinfo-data' to your Gemfile and run bundle install"
23
40
  end
24
41
  require "active_support/core_ext/time/zones"
25
- zone_default = Time.find_zone!(app.config.time_zone)
26
-
27
- unless zone_default
28
- raise "Value assigned to config.time_zone not recognized. " \
29
- 'Run "rake time:zones:all" for a time zone names list.'
30
- end
31
-
32
- Time.zone_default = zone_default
42
+ Time.zone_default = Time.find_zone!(app.config.time_zone)
33
43
  end
34
44
 
35
45
  # Sets the default week start
@@ -41,11 +51,30 @@ module ActiveSupport
41
51
  Date.beginning_of_week_default = beginning_of_week_default
42
52
  end
43
53
 
54
+ initializer "active_support.require_master_key" do |app|
55
+ if app.config.respond_to?(:require_master_key) && app.config.require_master_key
56
+ begin
57
+ app.credentials.key
58
+ rescue ActiveSupport::EncryptedFile::MissingKeyError => error
59
+ $stderr.puts error.message
60
+ exit 1
61
+ end
62
+ end
63
+ end
64
+
44
65
  initializer "active_support.set_configs" do |app|
45
66
  app.config.active_support.each do |k, v|
46
67
  k = "#{k}="
47
68
  ActiveSupport.send(k, v) if ActiveSupport.respond_to? k
48
69
  end
49
70
  end
71
+
72
+ initializer "active_support.set_hash_digest_class" do |app|
73
+ config.after_initialize do
74
+ if app.config.active_support.use_sha1_digests
75
+ ActiveSupport::Digest.hash_digest_class = ::Digest::SHA1
76
+ end
77
+ end
78
+ end
50
79
  end
51
80
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/execution_wrapper"
2
4
 
3
5
  module ActiveSupport
@@ -26,14 +28,17 @@ module ActiveSupport
26
28
 
27
29
  define_callbacks :class_unload
28
30
 
31
+ # Registers a callback that will run once at application startup and every time the code is reloaded.
29
32
  def self.to_prepare(*args, &block)
30
33
  set_callback(:prepare, *args, &block)
31
34
  end
32
35
 
36
+ # Registers a callback that will run immediately before the classes are unloaded.
33
37
  def self.before_class_unload(*args, &block)
34
38
  set_callback(:class_unload, *args, &block)
35
39
  end
36
40
 
41
+ # Registers a callback that will run immediately after the classes are unloaded.
37
42
  def self.after_class_unload(*args, &block)
38
43
  set_callback(:class_unload, :after, *args, &block)
39
44
  end
@@ -69,11 +74,8 @@ module ActiveSupport
69
74
  end
70
75
  end
71
76
 
72
- class_attribute :executor
73
- class_attribute :check
74
-
75
- self.executor = Executor
76
- self.check = lambda { false }
77
+ class_attribute :executor, default: Executor
78
+ class_attribute :check, default: lambda { false }
77
79
 
78
80
  def self.check! # :nodoc:
79
81
  @should_reload ||= check.call
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/concern"
2
4
  require "active_support/core_ext/class/attribute"
3
5
  require "active_support/core_ext/string/inflections"
@@ -8,8 +10,7 @@ module ActiveSupport
8
10
  extend Concern
9
11
 
10
12
  included do
11
- class_attribute :rescue_handlers
12
- self.rescue_handlers = []
13
+ class_attribute :rescue_handlers, default: []
13
14
  end
14
15
 
15
16
  module ClassMethods
@@ -1,15 +1,15 @@
1
- require "digest"
1
+ # frozen_string_literal: true
2
+
3
+ require "digest/sha2"
2
4
 
3
5
  module ActiveSupport
4
6
  module SecurityUtils
5
- # Constant time string comparison.
7
+ # Constant time string comparison, for fixed length strings.
6
8
  #
7
9
  # The values compared should be of fixed length, such as strings
8
- # that have already been processed by HMAC. This should not be used
9
- # on variable length plaintext strings because it could leak length info
10
- # via timing attacks.
11
- def secure_compare(a, b)
12
- return false unless a.bytesize == b.bytesize
10
+ # that have already been processed by HMAC. Raises in case of length mismatch.
11
+ def fixed_length_secure_compare(a, b)
12
+ raise ArgumentError, "string length mismatch." unless a.bytesize == b.bytesize
13
13
 
14
14
  l = a.unpack "C#{a.bytesize}"
15
15
 
@@ -17,11 +17,15 @@ module ActiveSupport
17
17
  b.each_byte { |byte| res |= byte ^ l.shift }
18
18
  res == 0
19
19
  end
20
- module_function :secure_compare
20
+ module_function :fixed_length_secure_compare
21
21
 
22
- def variable_size_secure_compare(a, b) # :nodoc:
23
- secure_compare(::Digest::SHA256.hexdigest(a), ::Digest::SHA256.hexdigest(b))
22
+ # Constant time string comparison, for variable length strings.
23
+ #
24
+ # The values are first processed by SHA256, so that we don't leak length info
25
+ # via timing attacks.
26
+ def secure_compare(a, b)
27
+ fixed_length_secure_compare(::Digest::SHA256.hexdigest(a), ::Digest::SHA256.hexdigest(b)) && a == b
24
28
  end
25
- module_function :variable_size_secure_compare
29
+ module_function :secure_compare
26
30
  end
27
31
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  # Wrapping a string in this class gives you a prettier way to test
3
5
  # for equality. The value returned by <tt>Rails.env</tt> is wrapped
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/per_thread_registry"
2
4
  require "active_support/notifications"
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/module/delegation"
2
4
  require "active_support/core_ext/object/blank"
3
5
  require "logger"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  gem "minitest" # make sure we get the gem, not stdlib
2
4
  require "minitest"
3
5
  require "active_support/testing/tagged_logging"
@@ -9,7 +11,6 @@ require "active_support/testing/isolation"
9
11
  require "active_support/testing/constant_lookup"
10
12
  require "active_support/testing/time_helpers"
11
13
  require "active_support/testing/file_fixtures"
12
- require "active_support/core_ext/kernel/reporting"
13
14
 
14
15
  module ActiveSupport
15
16
  class TestCase < ::Minitest::Test
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  module Testing
3
5
  module Assertions
@@ -56,6 +58,12 @@ module ActiveSupport
56
58
  # post :create, params: { article: {...} }
57
59
  # end
58
60
  #
61
+ # A hash of expressions/numeric differences can also be passed in and evaluated.
62
+ #
63
+ # assert_difference ->{ Article.count } => 1, ->{ Notification.count } => 2 do
64
+ # post :create, params: { article: {...} }
65
+ # end
66
+ #
59
67
  # A lambda or a list of lambdas can be passed in and evaluated:
60
68
  #
61
69
  # assert_difference ->{ Article.count }, 2 do
@@ -71,20 +79,28 @@ module ActiveSupport
71
79
  # assert_difference 'Article.count', -1, 'An Article should be destroyed' do
72
80
  # post :delete, params: { id: ... }
73
81
  # end
74
- def assert_difference(expression, difference = 1, message = nil, &block)
75
- expressions = Array(expression)
76
-
77
- exps = expressions.map { |e|
82
+ def assert_difference(expression, *args, &block)
83
+ expressions =
84
+ if expression.is_a?(Hash)
85
+ message = args[0]
86
+ expression
87
+ else
88
+ difference = args[0] || 1
89
+ message = args[1]
90
+ Hash[Array(expression).map { |e| [e, difference] }]
91
+ end
92
+
93
+ exps = expressions.keys.map { |e|
78
94
  e.respond_to?(:call) ? e : lambda { eval(e, block.binding) }
79
95
  }
80
96
  before = exps.map(&:call)
81
97
 
82
98
  retval = yield
83
99
 
84
- expressions.zip(exps).each_with_index do |(code, e), i|
85
- error = "#{code.inspect} didn't change by #{difference}"
100
+ expressions.zip(exps, before) do |(code, diff), exp, before_value|
101
+ error = "#{code.inspect} didn't change by #{diff}"
86
102
  error = "#{message}.\n#{error}" if message
87
- assert_equal(before[i] + difference, e.call, error)
103
+ assert_equal(before_value + diff, exp.call, error)
88
104
  end
89
105
 
90
106
  retval
@@ -154,11 +170,12 @@ module ActiveSupport
154
170
 
155
171
  after = exp.call
156
172
 
157
- if to == UNTRACKED
158
- error = "#{expression.inspect} didn't changed"
159
- error = "#{message}.\n#{error}" if message
160
- assert_not_equal before, after, error
161
- else
173
+ error = "#{expression.inspect} didn't change"
174
+ error = "#{error}. It was already #{to}" if before == to
175
+ error = "#{message}.\n#{error}" if message
176
+ assert before != after, error
177
+
178
+ unless to == UNTRACKED
162
179
  error = "#{expression.inspect} didn't change to #{to}"
163
180
  error = "#{message}.\n#{error}" if message
164
181
  assert to === after, error
@@ -167,7 +184,7 @@ module ActiveSupport
167
184
  retval
168
185
  end
169
186
 
170
- # Assertion that the result of evaluating an expression is changed before
187
+ # Assertion that the result of evaluating an expression is not changed before
171
188
  # and after invoking the passed in block.
172
189
  #
173
190
  # assert_no_changes 'Status.all_good?' do
@@ -188,7 +205,7 @@ module ActiveSupport
188
205
 
189
206
  error = "#{expression.inspect} did change to #{after}"
190
207
  error = "#{message}.\n#{error}" if message
191
- assert_equal before, after, error
208
+ assert before == after, error
192
209
 
193
210
  retval
194
211
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  gem "minitest"
2
4
 
3
5
  require "minitest"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/concern"
2
4
  require "active_support/inflector"
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  module Testing
3
5
  module Declarative
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/deprecation"
2
4
  require "active_support/core_ext/regexp"
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  module Testing
3
5
  # Adds simple access to sample files called file fixtures.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  module Testing
3
5
  module Isolation
@@ -54,7 +56,7 @@ module ActiveSupport
54
56
  write.close
55
57
  result = read.read
56
58
  Process.wait2(pid)
57
- return result.unpack("m")[0]
59
+ result.unpack("m")[0]
58
60
  end
59
61
  end
60
62
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "minitest/mock"
2
4
 
3
5
  module ActiveSupport
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/concern"
2
4
  require "active_support/callbacks"
3
5
 
@@ -42,8 +44,15 @@ module ActiveSupport
42
44
  end
43
45
 
44
46
  def after_teardown # :nodoc:
45
- run_callbacks :teardown
47
+ begin
48
+ run_callbacks :teardown
49
+ rescue => e
50
+ error = e
51
+ end
52
+
46
53
  super
54
+ ensure
55
+ raise error if error
47
56
  end
48
57
  end
49
58
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  module Testing
3
5
  module Stream #:nodoc:
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  module Testing
3
5
  # Logs a "PostsControllerTest: test name" heading before each test to
@@ -1,3 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/module/redefine_method"
1
4
  require "active_support/core_ext/string/strip" # for strip_heredoc
2
5
  require "active_support/core_ext/time/calculations"
3
6
  require "concurrent/map"
@@ -41,7 +44,7 @@ module ActiveSupport
41
44
 
42
45
  def unstub_object(stub)
43
46
  singleton_class = stub.object.singleton_class
44
- singleton_class.send :undef_method, stub.method_name
47
+ singleton_class.send :silence_redefinition_of_method, stub.method_name
45
48
  singleton_class.send :alias_method, stub.method_name, stub.original_method
46
49
  singleton_class.send :undef_method, stub.original_method
47
50
  end
@@ -49,8 +52,14 @@ module ActiveSupport
49
52
 
50
53
  # Contains helpers that help you test passage of time.
51
54
  module TimeHelpers
55
+ def after_teardown
56
+ travel_back
57
+ super
58
+ end
59
+
52
60
  # Changes current time to the time in the future or in the past by a given time difference by
53
- # stubbing +Time.now+, +Date.today+, and +DateTime.now+.
61
+ # stubbing +Time.now+, +Date.today+, and +DateTime.now+. The stubs are automatically removed
62
+ # at the end of the test.
54
63
  #
55
64
  # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
56
65
  # travel 1.day
@@ -72,6 +81,7 @@ module ActiveSupport
72
81
 
73
82
  # Changes current time to the given time by stubbing +Time.now+,
74
83
  # +Date.today+, and +DateTime.now+ to return the time or date passed into this method.
84
+ # The stubs are automatically removed at the end of the test.
75
85
  #
76
86
  # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
77
87
  # travel_to Time.zone.local(2004, 11, 24, 01, 04, 44)
@@ -149,7 +159,7 @@ module ActiveSupport
149
159
  end
150
160
 
151
161
  # Returns the current time back to its original state, by removing the stubs added by
152
- # `travel` and `travel_to`.
162
+ # +travel+ and +travel_to+.
153
163
  #
154
164
  # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
155
165
  # travel_to Time.zone.local(2004, 11, 24, 01, 04, 44)
@@ -160,6 +170,26 @@ module ActiveSupport
160
170
  simple_stubs.unstub_all!
161
171
  end
162
172
 
173
+ # Calls +travel_to+ with +Time.now+.
174
+ #
175
+ # Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00
176
+ # freeze_time
177
+ # sleep(1)
178
+ # Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00
179
+ #
180
+ # This method also accepts a block, which will return the current time back to its original
181
+ # state at the end of the block:
182
+ #
183
+ # Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00
184
+ # freeze_time do
185
+ # sleep(1)
186
+ # User.create.created_at # => Sun, 09 Jul 2017 15:34:49 EST -05:00
187
+ # end
188
+ # Time.current # => Sun, 09 Jul 2017 15:34:50 EST -05:00
189
+ def freeze_time(&block)
190
+ travel_to Time.now, &block
191
+ end
192
+
163
193
  private
164
194
 
165
195
  def simple_stubs
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  autoload :Duration, "active_support/duration"
3
5
  autoload :TimeWithZone, "active_support/time_with_zone"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/duration"
2
4
  require "active_support/values/time_zone"
3
5
  require "active_support/core_ext/object/acts_like"
@@ -330,6 +332,42 @@ module ActiveSupport
330
332
  since(-other)
331
333
  end
332
334
 
335
+ # Returns a new +ActiveSupport::TimeWithZone+ where one or more of the elements have
336
+ # been changed according to the +options+ parameter. The time options (<tt>:hour</tt>,
337
+ # <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly,
338
+ # so if only the hour is passed, then minute, sec, usec and nsec is set to 0. If the
339
+ # hour and minute is passed, then sec, usec and nsec is set to 0. The +options+
340
+ # parameter takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>,
341
+ # <tt>:day</tt>, <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>,
342
+ # <tt>:nsec</tt>, <tt>:offset</tt>, <tt>:zone</tt>. Pass either <tt>:usec</tt>
343
+ # or <tt>:nsec</tt>, not both. Similarly, pass either <tt>:zone</tt> or
344
+ # <tt>:offset</tt>, not both.
345
+ #
346
+ # t = Time.zone.now # => Fri, 14 Apr 2017 11:45:15 EST -05:00
347
+ # t.change(year: 2020) # => Tue, 14 Apr 2020 11:45:15 EST -05:00
348
+ # t.change(hour: 12) # => Fri, 14 Apr 2017 12:00:00 EST -05:00
349
+ # t.change(min: 30) # => Fri, 14 Apr 2017 11:30:00 EST -05:00
350
+ # t.change(offset: "-10:00") # => Fri, 14 Apr 2017 11:45:15 HST -10:00
351
+ # t.change(zone: "Hawaii") # => Fri, 14 Apr 2017 11:45:15 HST -10:00
352
+ def change(options)
353
+ if options[:zone] && options[:offset]
354
+ raise ArgumentError, "Can't change both :offset and :zone at the same time: #{options.inspect}"
355
+ end
356
+
357
+ new_time = time.change(options)
358
+
359
+ if options[:zone]
360
+ new_zone = ::Time.find_zone(options[:zone])
361
+ elsif options[:offset]
362
+ new_zone = ::Time.find_zone(new_time.utc_offset)
363
+ end
364
+
365
+ new_zone ||= time_zone
366
+ periods = new_zone.periods_for_local(new_time)
367
+
368
+ self.class.new(nil, new_zone, new_time, periods.include?(period) ? period : nil)
369
+ end
370
+
333
371
  # Uses Date to provide precise Time calculations for years, months, and days
334
372
  # according to the proleptic Gregorian calendar. The result is returned as a
335
373
  # new TimeWithZone object.