activesupport 5.0.7.2 → 5.1.0.beta1

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 (210) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +215 -820
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/lib/active_support.rb +8 -4
  6. data/lib/active_support/all.rb +3 -3
  7. data/lib/active_support/array_inquirer.rb +7 -5
  8. data/lib/active_support/backtrace_cleaner.rb +4 -4
  9. data/lib/active_support/benchmarkable.rb +3 -3
  10. data/lib/active_support/builder.rb +1 -1
  11. data/lib/active_support/cache.rb +42 -49
  12. data/lib/active_support/cache/file_store.rb +12 -21
  13. data/lib/active_support/cache/mem_cache_store.rb +30 -40
  14. data/lib/active_support/cache/memory_store.rb +11 -13
  15. data/lib/active_support/cache/null_store.rb +4 -4
  16. data/lib/active_support/cache/strategy/local_cache.rb +16 -25
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +8 -9
  18. data/lib/active_support/callbacks.rb +647 -584
  19. data/lib/active_support/concurrency/share_lock.rb +20 -21
  20. data/lib/active_support/configurable.rb +5 -5
  21. data/lib/active_support/core_ext.rb +1 -2
  22. data/lib/active_support/core_ext/array.rb +7 -7
  23. data/lib/active_support/core_ext/array/access.rb +1 -1
  24. data/lib/active_support/core_ext/array/conversions.rb +15 -15
  25. data/lib/active_support/core_ext/array/grouping.rb +1 -1
  26. data/lib/active_support/core_ext/array/inquiry.rb +1 -1
  27. data/lib/active_support/core_ext/array/prepend_and_append.rb +1 -1
  28. data/lib/active_support/core_ext/benchmark.rb +1 -1
  29. data/lib/active_support/core_ext/big_decimal.rb +1 -1
  30. data/lib/active_support/core_ext/big_decimal/conversions.rb +4 -6
  31. data/lib/active_support/core_ext/class.rb +2 -2
  32. data/lib/active_support/core_ext/class/attribute.rb +5 -5
  33. data/lib/active_support/core_ext/class/attribute_accessors.rb +1 -1
  34. data/lib/active_support/core_ext/class/subclasses.rb +18 -4
  35. data/lib/active_support/core_ext/date.rb +5 -5
  36. data/lib/active_support/core_ext/date/acts_like.rb +1 -1
  37. data/lib/active_support/core_ext/date/blank.rb +1 -1
  38. data/lib/active_support/core_ext/date/calculations.rb +8 -8
  39. data/lib/active_support/core_ext/date/conversions.rb +12 -12
  40. data/lib/active_support/core_ext/date/zones.rb +2 -2
  41. data/lib/active_support/core_ext/date_and_time/calculations.rb +27 -22
  42. data/lib/active_support/core_ext/date_and_time/compatibility.rb +9 -1
  43. data/lib/active_support/core_ext/date_and_time/zones.rb +7 -8
  44. data/lib/active_support/core_ext/date_time.rb +5 -5
  45. data/lib/active_support/core_ext/date_time/acts_like.rb +2 -2
  46. data/lib/active_support/core_ext/date_time/blank.rb +1 -1
  47. data/lib/active_support/core_ext/date_time/calculations.rb +9 -9
  48. data/lib/active_support/core_ext/date_time/compatibility.rb +2 -13
  49. data/lib/active_support/core_ext/date_time/conversions.rb +12 -12
  50. data/lib/active_support/core_ext/digest/uuid.rb +4 -4
  51. data/lib/active_support/core_ext/enumerable.rb +46 -57
  52. data/lib/active_support/core_ext/file.rb +1 -1
  53. data/lib/active_support/core_ext/file/atomic.rb +4 -4
  54. data/lib/active_support/core_ext/hash.rb +9 -9
  55. data/lib/active_support/core_ext/hash/compact.rb +12 -9
  56. data/lib/active_support/core_ext/hash/conversions.rb +36 -37
  57. data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -2
  58. data/lib/active_support/core_ext/hash/keys.rb +8 -8
  59. data/lib/active_support/core_ext/hash/reverse_merge.rb +1 -1
  60. data/lib/active_support/core_ext/hash/slice.rb +4 -4
  61. data/lib/active_support/core_ext/hash/transform_values.rb +1 -0
  62. data/lib/active_support/core_ext/integer.rb +3 -3
  63. data/lib/active_support/core_ext/integer/inflections.rb +1 -1
  64. data/lib/active_support/core_ext/integer/time.rb +2 -2
  65. data/lib/active_support/core_ext/kernel.rb +4 -4
  66. data/lib/active_support/core_ext/kernel/concern.rb +1 -1
  67. data/lib/active_support/core_ext/kernel/reporting.rb +1 -1
  68. data/lib/active_support/core_ext/load_error.rb +1 -18
  69. data/lib/active_support/core_ext/marshal.rb +2 -2
  70. data/lib/active_support/core_ext/module.rb +11 -12
  71. data/lib/active_support/core_ext/module/aliasing.rb +3 -48
  72. data/lib/active_support/core_ext/module/attr_internal.rb +4 -4
  73. data/lib/active_support/core_ext/module/attribute_accessors.rb +11 -5
  74. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +20 -13
  75. data/lib/active_support/core_ext/module/concerning.rb +1 -1
  76. data/lib/active_support/core_ext/module/delegation.rb +82 -16
  77. data/lib/active_support/core_ext/module/introspection.rb +3 -11
  78. data/lib/active_support/core_ext/module/reachable.rb +2 -2
  79. data/lib/active_support/core_ext/numeric.rb +4 -4
  80. data/lib/active_support/core_ext/numeric/conversions.rb +3 -9
  81. data/lib/active_support/core_ext/numeric/inquiry.rb +21 -21
  82. data/lib/active_support/core_ext/numeric/time.rb +5 -5
  83. data/lib/active_support/core_ext/object.rb +12 -12
  84. data/lib/active_support/core_ext/object/blank.rb +3 -1
  85. data/lib/active_support/core_ext/object/conversions.rb +4 -4
  86. data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
  87. data/lib/active_support/core_ext/object/duplicable.rb +24 -4
  88. data/lib/active_support/core_ext/object/inclusion.rb +1 -1
  89. data/lib/active_support/core_ext/object/json.rb +26 -12
  90. data/lib/active_support/core_ext/object/to_param.rb +1 -1
  91. data/lib/active_support/core_ext/object/to_query.rb +4 -4
  92. data/lib/active_support/core_ext/object/try.rb +1 -1
  93. data/lib/active_support/core_ext/object/with_options.rb +1 -1
  94. data/lib/active_support/core_ext/range.rb +4 -4
  95. data/lib/active_support/core_ext/range/conversions.rb +1 -1
  96. data/lib/active_support/core_ext/regexp.rb +4 -0
  97. data/lib/active_support/core_ext/securerandom.rb +3 -3
  98. data/lib/active_support/core_ext/string.rb +13 -13
  99. data/lib/active_support/core_ext/string/access.rb +6 -6
  100. data/lib/active_support/core_ext/string/conversions.rb +2 -2
  101. data/lib/active_support/core_ext/string/filters.rb +3 -3
  102. data/lib/active_support/core_ext/string/indent.rb +4 -4
  103. data/lib/active_support/core_ext/string/inflections.rb +10 -14
  104. data/lib/active_support/core_ext/string/inquiry.rb +1 -1
  105. data/lib/active_support/core_ext/string/multibyte.rb +1 -1
  106. data/lib/active_support/core_ext/string/output_safety.rb +19 -20
  107. data/lib/active_support/core_ext/string/strip.rb +1 -1
  108. data/lib/active_support/core_ext/string/zones.rb +2 -2
  109. data/lib/active_support/core_ext/time.rb +5 -5
  110. data/lib/active_support/core_ext/time/acts_like.rb +1 -1
  111. data/lib/active_support/core_ext/time/calculations.rb +23 -29
  112. data/lib/active_support/core_ext/time/compatibility.rb +1 -10
  113. data/lib/active_support/core_ext/time/conversions.rb +12 -12
  114. data/lib/active_support/core_ext/time/zones.rb +3 -3
  115. data/lib/active_support/core_ext/uri.rb +2 -2
  116. data/lib/active_support/dependencies.rb +45 -47
  117. data/lib/active_support/dependencies/interlock.rb +1 -1
  118. data/lib/active_support/deprecation.rb +8 -8
  119. data/lib/active_support/deprecation/behaviors.rb +3 -3
  120. data/lib/active_support/deprecation/instance_delegator.rb +2 -2
  121. data/lib/active_support/deprecation/method_wrappers.rb +3 -3
  122. data/lib/active_support/deprecation/proxy_wrappers.rb +6 -4
  123. data/lib/active_support/deprecation/reporting.rb +7 -7
  124. data/lib/active_support/duration.rb +30 -26
  125. data/lib/active_support/duration/iso8601_parser.rb +66 -65
  126. data/lib/active_support/duration/iso8601_serializer.rb +11 -9
  127. data/lib/active_support/evented_file_update_checker.rb +59 -60
  128. data/lib/active_support/execution_wrapper.rb +3 -3
  129. data/lib/active_support/executor.rb +1 -1
  130. data/lib/active_support/file_update_checker.rb +54 -50
  131. data/lib/active_support/gem_version.rb +3 -3
  132. data/lib/active_support/gzip.rb +5 -5
  133. data/lib/active_support/hash_with_indifferent_access.rb +10 -20
  134. data/lib/active_support/i18n.rb +5 -5
  135. data/lib/active_support/i18n_railtie.rb +11 -10
  136. data/lib/active_support/inflections.rb +11 -11
  137. data/lib/active_support/inflector.rb +5 -5
  138. data/lib/active_support/inflector/inflections.rb +11 -9
  139. data/lib/active_support/inflector/methods.rb +51 -50
  140. data/lib/active_support/inflector/transliterate.rb +8 -11
  141. data/lib/active_support/json.rb +2 -2
  142. data/lib/active_support/json/decoding.rb +3 -3
  143. data/lib/active_support/json/encoding.rb +8 -7
  144. data/lib/active_support/key_generator.rb +17 -17
  145. data/lib/active_support/lazy_load_hooks.rb +12 -30
  146. data/lib/active_support/log_subscriber.rb +5 -5
  147. data/lib/active_support/log_subscriber/test_helper.rb +9 -9
  148. data/lib/active_support/logger.rb +3 -3
  149. data/lib/active_support/logger_silence.rb +3 -3
  150. data/lib/active_support/logger_thread_safe_level.rb +1 -1
  151. data/lib/active_support/message_encryptor.rb +72 -35
  152. data/lib/active_support/message_verifier.rb +7 -7
  153. data/lib/active_support/multibyte.rb +2 -2
  154. data/lib/active_support/multibyte/chars.rb +23 -21
  155. data/lib/active_support/multibyte/unicode.rb +68 -89
  156. data/lib/active_support/notifications.rb +5 -5
  157. data/lib/active_support/notifications/fanout.rb +3 -3
  158. data/lib/active_support/notifications/instrumenter.rb +5 -5
  159. data/lib/active_support/number_helper.rb +4 -4
  160. data/lib/active_support/number_helper/number_converter.rb +11 -11
  161. data/lib/active_support/number_helper/number_to_currency_converter.rb +3 -3
  162. data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -2
  163. data/lib/active_support/number_helper/number_to_human_converter.rb +6 -6
  164. data/lib/active_support/number_helper/number_to_human_size_converter.rb +6 -11
  165. data/lib/active_support/number_helper/number_to_percentage_converter.rb +1 -1
  166. data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -3
  167. data/lib/active_support/number_helper/number_to_rounded_converter.rb +6 -6
  168. data/lib/active_support/option_merger.rb +1 -1
  169. data/lib/active_support/ordered_hash.rb +3 -3
  170. data/lib/active_support/ordered_options.rb +6 -4
  171. data/lib/active_support/per_thread_registry.rb +5 -5
  172. data/lib/active_support/rails.rb +12 -6
  173. data/lib/active_support/railtie.rb +3 -3
  174. data/lib/active_support/reloader.rb +1 -1
  175. data/lib/active_support/rescuable.rb +8 -14
  176. data/lib/active_support/security_utils.rb +1 -1
  177. data/lib/active_support/string_inquirer.rb +8 -2
  178. data/lib/active_support/subscriber.rb +9 -5
  179. data/lib/active_support/tagged_logging.rb +4 -4
  180. data/lib/active_support/test_case.rb +12 -29
  181. data/lib/active_support/testing/assertions.rb +100 -2
  182. data/lib/active_support/testing/autorun.rb +6 -2
  183. data/lib/active_support/testing/constant_lookup.rb +0 -1
  184. data/lib/active_support/testing/declarative.rb +1 -1
  185. data/lib/active_support/testing/deprecation.rb +3 -2
  186. data/lib/active_support/testing/isolation.rb +13 -22
  187. data/lib/active_support/testing/method_call_assertions.rb +1 -1
  188. data/lib/active_support/testing/setup_and_teardown.rb +2 -2
  189. data/lib/active_support/testing/stream.rb +28 -28
  190. data/lib/active_support/testing/tagged_logging.rb +1 -1
  191. data/lib/active_support/testing/time_helpers.rb +45 -12
  192. data/lib/active_support/time.rb +12 -12
  193. data/lib/active_support/time_with_zone.rb +16 -26
  194. data/lib/active_support/values/time_zone.rb +40 -46
  195. data/lib/active_support/values/unicode_tables.dat +0 -0
  196. data/lib/active_support/version.rb +1 -1
  197. data/lib/active_support/xml_mini.rb +34 -36
  198. data/lib/active_support/xml_mini/jdom.rb +112 -112
  199. data/lib/active_support/xml_mini/libxml.rb +15 -12
  200. data/lib/active_support/xml_mini/libxmlsax.rb +17 -15
  201. data/lib/active_support/xml_mini/nokogiri.rb +13 -11
  202. data/lib/active_support/xml_mini/nokogirisax.rb +15 -14
  203. data/lib/active_support/xml_mini/rexml.rb +9 -9
  204. metadata +8 -19
  205. data/lib/active_support/concurrency/latch.rb +0 -26
  206. data/lib/active_support/core_ext/kernel/debugger.rb +0 -3
  207. data/lib/active_support/core_ext/module/method_transplanting.rb +0 -3
  208. data/lib/active_support/core_ext/module/qualified_const.rb +0 -70
  209. data/lib/active_support/core_ext/struct.rb +0 -3
  210. data/lib/active_support/core_ext/time/marshal.rb +0 -3
@@ -2,7 +2,7 @@ require "active_support/notifications"
2
2
 
3
3
  module ActiveSupport
4
4
  # Raised when <tt>ActiveSupport::Deprecation::Behavior#behavior</tt> is set with <tt>:raise</tt>.
5
- # You would set <tt>:raise</tt>, as a behaviour to raise errors and proactively report exceptions from deprecations.
5
+ # You would set <tt>:raise</tt>, as a behavior to raise errors and proactively report exceptions from deprecations.
6
6
  class DeprecationException < StandardError
7
7
  end
8
8
 
@@ -25,7 +25,7 @@ module ActiveSupport
25
25
  if defined?(Rails.logger) && Rails.logger
26
26
  Rails.logger
27
27
  else
28
- require 'active_support/logger'
28
+ require "active_support/logger"
29
29
  ActiveSupport::Logger.new($stderr)
30
30
  end
31
31
  logger.warn message
@@ -34,7 +34,7 @@ module ActiveSupport
34
34
 
35
35
  notify: ->(message, callstack) {
36
36
  ActiveSupport::Notifications.instrument("deprecation.rails",
37
- :message => message, :callstack => callstack)
37
+ message: message, callstack: callstack)
38
38
  },
39
39
 
40
40
  silence: ->(message, callstack) {},
@@ -1,5 +1,5 @@
1
- require 'active_support/core_ext/kernel/singleton_class'
2
- require 'active_support/core_ext/module/delegation'
1
+ require "active_support/core_ext/kernel/singleton_class"
2
+ require "active_support/core_ext/module/delegation"
3
3
 
4
4
  module ActiveSupport
5
5
  class Deprecation
@@ -1,5 +1,5 @@
1
- require 'active_support/core_ext/module/aliasing'
2
- require 'active_support/core_ext/array/extract_options'
1
+ require "active_support/core_ext/module/aliasing"
2
+ require "active_support/core_ext/array/extract_options"
3
3
 
4
4
  module ActiveSupport
5
5
  class Deprecation
@@ -18,7 +18,7 @@ module ActiveSupport
18
18
  #
19
19
  # Using the default deprecator:
20
20
  # ActiveSupport::Deprecation.deprecate_methods(Fred, :aaa, bbb: :zzz, ccc: 'use Bar#ccc instead')
21
- # # => [:aaa, :bbb, :ccc]
21
+ # # => Fred
22
22
  #
23
23
  # Fred.aaa
24
24
  # # DEPRECATION WARNING: aaa is deprecated and will be removed from Rails 5.1. (called from irb_binding at (irb):10)
@@ -1,4 +1,5 @@
1
- require 'active_support/inflector/methods'
1
+ require "active_support/inflector/methods"
2
+ require "active_support/core_ext/regexp"
2
3
 
3
4
  module ActiveSupport
4
5
  class Deprecation
@@ -10,7 +11,7 @@ module ActiveSupport
10
11
  super
11
12
  end
12
13
 
13
- instance_methods.each { |m| undef_method m unless m =~ /^__|^object_id$/ }
14
+ instance_methods.each { |m| undef_method m unless /^__|^object_id$/.match?(m) }
14
15
 
15
16
  # Don't give a deprecation warning on inspect since test/unit and error
16
17
  # logs rely on it for diagnostics.
@@ -121,10 +122,11 @@ module ActiveSupport
121
122
  # (Backtrace information…)
122
123
  # ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"]
123
124
  class DeprecatedConstantProxy < DeprecationProxy
124
- def initialize(old_const, new_const, deprecator = ActiveSupport::Deprecation.instance)
125
+ def initialize(old_const, new_const, deprecator = ActiveSupport::Deprecation.instance, message: "#{old_const} is deprecated! Use #{new_const} instead.")
125
126
  @old_const = old_const
126
127
  @new_const = new_const
127
128
  @deprecator = deprecator
129
+ @message = message
128
130
  end
129
131
 
130
132
  # Returns the class of the new constant.
@@ -142,7 +144,7 @@ module ActiveSupport
142
144
  end
143
145
 
144
146
  def warn(callstack, called, args)
145
- @deprecator.warn("#{@old_const} is deprecated! Use #{@new_const} instead.", callstack)
147
+ @deprecator.warn(@message, callstack)
146
148
  end
147
149
  end
148
150
  end
@@ -1,4 +1,4 @@
1
- require 'rbconfig'
1
+ require "rbconfig"
2
2
 
3
3
  module ActiveSupport
4
4
  class Deprecation
@@ -48,17 +48,17 @@ module ActiveSupport
48
48
  private
49
49
  # Outputs a deprecation warning message
50
50
  #
51
- # ActiveSupport::Deprecation.deprecated_method_warning(:method_name)
51
+ # deprecated_method_warning(:method_name)
52
52
  # # => "method_name is deprecated and will be removed from Rails #{deprecation_horizon}"
53
- # ActiveSupport::Deprecation.deprecated_method_warning(:method_name, :another_method)
53
+ # deprecated_method_warning(:method_name, :another_method)
54
54
  # # => "method_name is deprecated and will be removed from Rails #{deprecation_horizon} (use another_method instead)"
55
- # ActiveSupport::Deprecation.deprecated_method_warning(:method_name, "Optional message")
55
+ # deprecated_method_warning(:method_name, "Optional message")
56
56
  # # => "method_name is deprecated and will be removed from Rails #{deprecation_horizon} (Optional message)"
57
57
  def deprecated_method_warning(method_name, message = nil)
58
58
  warning = "#{method_name} is deprecated and will be removed from #{gem_name} #{deprecation_horizon}"
59
59
  case message
60
- when Symbol then "#{warning} (use #{message} instead)"
61
- when String then "#{warning} (#{message})"
60
+ when Symbol then "#{warning} (use #{message} instead)"
61
+ when String then "#{warning} (#{message})"
62
62
  else warning
63
63
  end
64
64
  end
@@ -105,7 +105,7 @@ module ActiveSupport
105
105
  RAILS_GEM_ROOT = File.expand_path("../../../../..", __FILE__) + "/"
106
106
 
107
107
  def ignored_callstack(path)
108
- path.start_with?(RAILS_GEM_ROOT) || path.start_with?(RbConfig::CONFIG['rubylibdir'])
108
+ path.start_with?(RAILS_GEM_ROOT) || path.start_with?(RbConfig::CONFIG["rubylibdir"])
109
109
  end
110
110
  end
111
111
  end
@@ -1,5 +1,5 @@
1
- require 'active_support/core_ext/array/conversions'
2
- require 'active_support/core_ext/object/acts_like'
1
+ require "active_support/core_ext/array/conversions"
2
+ require "active_support/core_ext/object/acts_like"
3
3
 
4
4
  module ActiveSupport
5
5
  # Provides accurate date and time measurements using Date#advance and
@@ -11,8 +11,8 @@ module ActiveSupport
11
11
  SECONDS_PER_HOUR = 3600
12
12
  SECONDS_PER_DAY = 86400
13
13
  SECONDS_PER_WEEK = 604800
14
- SECONDS_PER_MONTH = 2592000 # 30 days
15
- SECONDS_PER_YEAR = 31557600 # length of a julian year (365.2425 days)
14
+ SECONDS_PER_MONTH = 2629746 # 1/12 of a gregorian year
15
+ SECONDS_PER_YEAR = 31556952 # length of a gregorian year (365.2425 days)
16
16
 
17
17
  PARTS_IN_SECONDS = {
18
18
  seconds: 1,
@@ -26,8 +26,8 @@ module ActiveSupport
26
26
 
27
27
  attr_accessor :value, :parts
28
28
 
29
- autoload :ISO8601Parser, 'active_support/duration/iso8601_parser'
30
- autoload :ISO8601Serializer, 'active_support/duration/iso8601_serializer'
29
+ autoload :ISO8601Parser, "active_support/duration/iso8601_parser"
30
+ autoload :ISO8601Serializer, "active_support/duration/iso8601_serializer"
31
31
 
32
32
  class << self
33
33
  # Creates a new Duration from string formatted according to ISO 8601 Duration.
@@ -84,16 +84,22 @@ module ActiveSupport
84
84
  end
85
85
 
86
86
  def initialize(value, parts) #:nodoc:
87
- @value, @parts = value, parts
87
+ @value, @parts = value, parts.to_h
88
+ @parts.default = 0
88
89
  end
89
90
 
90
91
  # Adds another Duration or a Numeric to this Duration. Numeric values
91
92
  # are treated as seconds.
92
93
  def +(other)
93
94
  if Duration === other
94
- Duration.new(value + other.value, @parts + other.parts)
95
+ parts = @parts.dup
96
+ other.parts.each do |(key, value)|
97
+ parts[key] += value
98
+ end
99
+ Duration.new(value + other.value, parts)
95
100
  else
96
- Duration.new(value + other, @parts + [[:seconds, other]])
101
+ seconds = @parts[:seconds] + other
102
+ Duration.new(value + other, @parts.merge(seconds: seconds))
97
103
  end
98
104
  end
99
105
 
@@ -104,7 +110,7 @@ module ActiveSupport
104
110
  end
105
111
 
106
112
  def -@ #:nodoc:
107
- Duration.new(-value, parts.map { |type,number| [type, -number] })
113
+ Duration.new(-value, parts.map { |type, number| [type, -number] })
108
114
  end
109
115
 
110
116
  def is_a?(klass) #:nodoc:
@@ -141,14 +147,14 @@ module ActiveSupport
141
147
  # 1.day.to_i # => 86400
142
148
  #
143
149
  # Note that this conversion makes some assumptions about the
144
- # duration of some periods, e.g. months are always 30 days
145
- # and years are 365.25 days:
150
+ # duration of some periods, e.g. months are always 1/12 of year
151
+ # and years are 365.2425 days:
146
152
  #
147
- # # equivalent to 30.days.to_i
148
- # 1.month.to_i # => 2592000
153
+ # # equivalent to (1.year / 12).to_i
154
+ # 1.month.to_i # => 2629746
149
155
  #
150
- # # equivalent to 365.25.days.to_i
151
- # 1.year.to_i # => 31557600
156
+ # # equivalent to 365.2425.days.to_i
157
+ # 1.year.to_i # => 31556952
152
158
  #
153
159
  # In such cases, Ruby's core
154
160
  # Date[http://ruby-doc.org/stdlib/libdoc/date/rdoc/Date.html] and
@@ -184,9 +190,9 @@ module ActiveSupport
184
190
 
185
191
  def inspect #:nodoc:
186
192
  parts.
187
- reduce(::Hash.new(0)) { |h,(l,r)| h[l] += r; h }.
188
- sort_by {|unit, _ | [:years, :months, :weeks, :days, :hours, :minutes, :seconds].index(unit)}.
189
- map {|unit, val| "#{val} #{val == 1 ? unit.to_s.chop : unit.to_s}"}.
193
+ reduce(::Hash.new(0)) { |h, (l, r)| h[l] += r; h }.
194
+ sort_by { |unit, _ | [:years, :months, :weeks, :days, :hours, :minutes, :seconds].index(unit) }.
195
+ map { |unit, val| "#{val} #{val == 1 ? unit.to_s.chop : unit.to_s}" }.
190
196
  to_sentence(locale: ::I18n.default_locale)
191
197
  end
192
198
 
@@ -194,7 +200,7 @@ module ActiveSupport
194
200
  to_i
195
201
  end
196
202
 
197
- def respond_to_missing?(method, include_private=false) #:nodoc:
203
+ def respond_to_missing?(method, include_private = false) #:nodoc:
198
204
  @value.respond_to?(method, include_private)
199
205
  end
200
206
 
@@ -206,10 +212,10 @@ module ActiveSupport
206
212
 
207
213
  delegate :<=>, to: :value
208
214
 
209
- protected
215
+ private
210
216
 
211
- def sum(sign, time = ::Time.current) #:nodoc:
212
- parts.inject(time) do |t,(type,number)|
217
+ def sum(sign, time = ::Time.current)
218
+ parts.inject(time) do |t, (type, number)|
213
219
  if t.acts_like?(:time) || t.acts_like?(:date)
214
220
  if type == :seconds
215
221
  t.since(sign * number)
@@ -226,9 +232,7 @@ module ActiveSupport
226
232
  end
227
233
  end
228
234
 
229
- private
230
-
231
- def method_missing(method, *args, &block) #:nodoc:
235
+ def method_missing(method, *args, &block)
232
236
  value.send(method, *args, &block)
233
237
  end
234
238
  end
@@ -1,4 +1,5 @@
1
- require 'strscan'
1
+ require "strscan"
2
+ require "active_support/core_ext/regexp"
2
3
 
3
4
  module ActiveSupport
4
5
  class Duration
@@ -11,8 +12,8 @@ module ActiveSupport
11
12
  class ParsingError < ::ArgumentError; end
12
13
 
13
14
  PERIOD_OR_COMMA = /\.|,/
14
- PERIOD = '.'.freeze
15
- COMMA = ','.freeze
15
+ PERIOD = ".".freeze
16
+ COMMA = ",".freeze
16
17
 
17
18
  SIGN_MARKER = /\A\-|\+|/
18
19
  DATE_MARKER = /P/
@@ -20,8 +21,8 @@ module ActiveSupport
20
21
  DATE_COMPONENT = /(\-?\d+(?:[.,]\d+)?)(Y|M|D|W)/
21
22
  TIME_COMPONENT = /(\-?\d+(?:[.,]\d+)?)(H|M|S)/
22
23
 
23
- DATE_TO_PART = { 'Y' => :years, 'M' => :months, 'W' => :weeks, 'D' => :days }
24
- TIME_TO_PART = { 'H' => :hours, 'M' => :minutes, 'S' => :seconds }
24
+ DATE_TO_PART = { "Y" => :years, "M" => :months, "W" => :weeks, "D" => :days }
25
+ TIME_TO_PART = { "H" => :hours, "M" => :minutes, "S" => :seconds }
25
26
 
26
27
  DATE_COMPONENTS = [:years, :months, :days]
27
28
  TIME_COMPONENTS = [:hours, :minutes, :seconds]
@@ -39,36 +40,36 @@ module ActiveSupport
39
40
  def parse!
40
41
  while !finished?
41
42
  case mode
42
- when :start
43
- if scan(SIGN_MARKER)
44
- self.sign = (scanner.matched == '-') ? -1 : 1
45
- self.mode = :sign
46
- else
47
- raise_parsing_error
48
- end
49
-
50
- when :sign
51
- if scan(DATE_MARKER)
52
- self.mode = :date
53
- else
54
- raise_parsing_error
55
- end
56
-
57
- when :date
58
- if scan(TIME_MARKER)
59
- self.mode = :time
60
- elsif scan(DATE_COMPONENT)
61
- parts[DATE_TO_PART[scanner[2]]] = number * sign
62
- else
63
- raise_parsing_error
64
- end
65
-
66
- when :time
67
- if scan(TIME_COMPONENT)
68
- parts[TIME_TO_PART[scanner[2]]] = number * sign
69
- else
70
- raise_parsing_error
71
- end
43
+ when :start
44
+ if scan(SIGN_MARKER)
45
+ self.sign = (scanner.matched == "-") ? -1 : 1
46
+ self.mode = :sign
47
+ else
48
+ raise_parsing_error
49
+ end
50
+
51
+ when :sign
52
+ if scan(DATE_MARKER)
53
+ self.mode = :date
54
+ else
55
+ raise_parsing_error
56
+ end
57
+
58
+ when :date
59
+ if scan(TIME_MARKER)
60
+ self.mode = :time
61
+ elsif scan(DATE_COMPONENT)
62
+ parts[DATE_TO_PART[scanner[2]]] = number * sign
63
+ else
64
+ raise_parsing_error
65
+ end
66
+
67
+ when :time
68
+ if scan(TIME_COMPONENT)
69
+ parts[TIME_TO_PART[scanner[2]]] = number * sign
70
+ else
71
+ raise_parsing_error
72
+ end
72
73
 
73
74
  end
74
75
  end
@@ -79,44 +80,44 @@ module ActiveSupport
79
80
 
80
81
  private
81
82
 
82
- def finished?
83
- scanner.eos?
84
- end
83
+ def finished?
84
+ scanner.eos?
85
+ end
85
86
 
86
- # Parses number which can be a float with either comma or period.
87
- def number
88
- scanner[1] =~ PERIOD_OR_COMMA ? scanner[1].tr(COMMA, PERIOD).to_f : scanner[1].to_i
89
- end
87
+ # Parses number which can be a float with either comma or period.
88
+ def number
89
+ PERIOD_OR_COMMA.match?(scanner[1]) ? scanner[1].tr(COMMA, PERIOD).to_f : scanner[1].to_i
90
+ end
90
91
 
91
- def scan(pattern)
92
- scanner.scan(pattern)
93
- end
92
+ def scan(pattern)
93
+ scanner.scan(pattern)
94
+ end
94
95
 
95
- def raise_parsing_error(reason = nil)
96
- raise ParsingError, "Invalid ISO 8601 duration: #{scanner.string.inspect} #{reason}".strip
97
- end
96
+ def raise_parsing_error(reason = nil)
97
+ raise ParsingError, "Invalid ISO 8601 duration: #{scanner.string.inspect} #{reason}".strip
98
+ end
98
99
 
99
- # Checks for various semantic errors as stated in ISO 8601 standard.
100
- def validate!
101
- raise_parsing_error('is empty duration') if parts.empty?
100
+ # Checks for various semantic errors as stated in ISO 8601 standard.
101
+ def validate!
102
+ raise_parsing_error("is empty duration") if parts.empty?
102
103
 
103
- # Mixing any of Y, M, D with W is invalid.
104
- if parts.key?(:weeks) && (parts.keys & DATE_COMPONENTS).any?
105
- raise_parsing_error('mixing weeks with other date parts not allowed')
106
- end
104
+ # Mixing any of Y, M, D with W is invalid.
105
+ if parts.key?(:weeks) && (parts.keys & DATE_COMPONENTS).any?
106
+ raise_parsing_error("mixing weeks with other date parts not allowed")
107
+ end
107
108
 
108
- # Specifying an empty T part is invalid.
109
- if mode == :time && (parts.keys & TIME_COMPONENTS).empty?
110
- raise_parsing_error('time part marker is present but time part is empty')
111
- end
109
+ # Specifying an empty T part is invalid.
110
+ if mode == :time && (parts.keys & TIME_COMPONENTS).empty?
111
+ raise_parsing_error("time part marker is present but time part is empty")
112
+ end
112
113
 
113
- fractions = parts.values.reject(&:zero?).select { |a| (a % 1) != 0 }
114
- unless fractions.empty? || (fractions.size == 1 && fractions.last == @parts.values.reject(&:zero?).last)
115
- raise_parsing_error '(only last part can be fractional)'
116
- end
114
+ fractions = parts.values.reject(&:zero?).select { |a| (a % 1) != 0 }
115
+ unless fractions.empty? || (fractions.size == 1 && fractions.last == @parts.values.reject(&:zero?).last)
116
+ raise_parsing_error "(only last part can be fractional)"
117
+ end
117
118
 
118
- return true
119
- end
119
+ return true
120
+ end
120
121
  end
121
122
  end
122
123
  end
@@ -1,10 +1,10 @@
1
- require 'active_support/core_ext/object/blank'
2
- require 'active_support/core_ext/hash/transform_values'
1
+ require "active_support/core_ext/object/blank"
2
+ require "active_support/core_ext/hash/transform_values"
3
3
 
4
4
  module ActiveSupport
5
5
  class Duration
6
6
  # Serializes duration to string according to ISO 8601 Duration format.
7
- class ISO8601Serializer
7
+ class ISO8601Serializer # :nodoc:
8
8
  def initialize(duration, precision: nil)
9
9
  @duration = duration
10
10
  @precision = precision
@@ -12,19 +12,21 @@ module ActiveSupport
12
12
 
13
13
  # Builds and returns output string.
14
14
  def serialize
15
- output = 'P'
16
15
  parts, sign = normalize
16
+ return "PT0S".freeze if parts.empty?
17
+
18
+ output = "P"
17
19
  output << "#{parts[:years]}Y" if parts.key?(:years)
18
20
  output << "#{parts[:months]}M" if parts.key?(:months)
19
21
  output << "#{parts[:weeks]}W" if parts.key?(:weeks)
20
22
  output << "#{parts[:days]}D" if parts.key?(:days)
21
- time = ''
23
+ time = ""
22
24
  time << "#{parts[:hours]}H" if parts.key?(:hours)
23
25
  time << "#{parts[:minutes]}M" if parts.key?(:minutes)
24
26
  if parts.key?(:seconds)
25
27
  time << "#{sprintf(@precision ? "%0.0#{@precision}f" : '%g', parts[:seconds])}S"
26
28
  end
27
- output << "T#{time}" if time.present?
29
+ output << "T#{time}" unless time.empty?
28
30
  "#{sign}#{output}"
29
31
  end
30
32
 
@@ -35,13 +37,13 @@ module ActiveSupport
35
37
  # Zero parts are removed as not significant.
36
38
  # If all parts are negative it will negate all of them and return minus as a sign.
37
39
  def normalize
38
- parts = @duration.parts.each_with_object(Hash.new(0)) do |(k,v),p|
40
+ parts = @duration.parts.each_with_object(Hash.new(0)) do |(k, v), p|
39
41
  p[k] += v unless v.zero?
40
42
  end
41
43
  # If all parts are negative - let's make a negative duration
42
- sign = ''
44
+ sign = ""
43
45
  if parts.values.all? { |v| v < 0 }
44
- sign = '-'
46
+ sign = "-"
45
47
  parts.transform_values!(&:-@)
46
48
  end
47
49
  [parts, sign]