activesupport 4.2.7.1 → 4.2.8.rc1

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.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b0e58a94c6f63279dd13ea4ce28f2925feb55429
4
- data.tar.gz: eed064f3db4c2352680b71573d0d6653ab962b16
3
+ metadata.gz: aef030d2267c2742dcea26abfa51945b44275d1f
4
+ data.tar.gz: 47439cba992d1e44f9e98eda1704cf1ef871aa40
5
5
  SHA512:
6
- metadata.gz: 8dd07baa24c81a20df4de6f0e3c2d59f19844f4140f85f0d65c4757c2ae4b162e76113bd403581f2d02fc6782d72893e783e7e8bfb17d54c432128c3649f862a
7
- data.tar.gz: 8a09a28701382208a803a9b915aa1a8d54bd05dd0dd93fbef8bbc428931c4d16ad5958f34734710e4fd44d7ebb8eb14411e246cd4839047a79813b187e2159e6
6
+ metadata.gz: 7309e18ce0a763ee489bab2d6242f321253388a2414907bf160e530f8df51b0169b6fcb33ab94fc0e6580c5b04d18acae9a6b90f11dab92b8b43d7020a6b0cad
7
+ data.tar.gz: 50db91760bf83296eb9fbce565d8f21632e539cf147d9d8ba3924a82665bd2153b3bcc67fdb95bb33515eb182343e669bce613b9c120382ce7326a4d1a9a275f
@@ -1,3 +1,97 @@
1
+ ## Rails 4.2.8.rc1 (February 09, 2017) ##
2
+
3
+ * Make `getlocal` and `getutc` always return instances of `Time` for
4
+ `ActiveSupport::TimeWithZone` and `DateTime`. This eliminates a possible
5
+ stack level too deep error in `to_time` where `ActiveSupport::TimeWithZone`
6
+ was wrapping a `DateTime` instance. As a consequence of this the internal
7
+ time value in `ActiveSupport::TimeWithZone` is now always an instance of
8
+ `Time` in the UTC timezone, whether that's as the UTC time directly or
9
+ a representation of the local time in the timezone. There should be no
10
+ consequences of this internal change and if there are it's a bug due to
11
+ leaky abstractions.
12
+
13
+ *Andrew White*
14
+
15
+ * Add `DateTime#subsec` to return the fraction of a second as a `Rational`.
16
+
17
+ *Andrew White*
18
+
19
+ * Add additional aliases for `DateTime#utc` to mirror the ones on
20
+ `ActiveSupport::TimeWithZone` and `Time`.
21
+
22
+ *Andrew White*
23
+
24
+ * Add `DateTime#localtime` to return an instance of `Time` in the system's
25
+ local timezone. Also aliased to `getlocal`.
26
+
27
+ *Andrew White*, *Yuichiro Kaneko*
28
+
29
+ * Add `Time#sec_fraction` to return the fraction of a second as a `Rational`.
30
+
31
+ *Andrew White*
32
+
33
+ * Add `ActiveSupport.to_time_preserves_timezone` config option to control
34
+ how `to_time` handles timezones. In Ruby 2.4+ the behavior will change
35
+ from converting to the local system timezone, to preserving the timezone
36
+ of the receiver. This config option defaults to false so that apps made
37
+ with earlier versions of Rails are not affected when upgrading, e.g:
38
+
39
+ >> ENV['TZ'] = 'US/Eastern'
40
+
41
+ >> "2016-04-23T10:23:12.000Z".to_time
42
+ => "2016-04-23T06:23:12.000-04:00"
43
+
44
+ >> ActiveSupport.to_time_preserves_timezone = true
45
+
46
+ >> "2016-04-23T10:23:12.000Z".to_time
47
+ => "2016-04-23T10:23:12.000Z"
48
+
49
+ Fixes #24617.
50
+
51
+ *Andrew White*
52
+
53
+ * Add `init_with` to `ActiveSupport::TimeWithZone` and `ActiveSupport::TimeZone`
54
+
55
+ It is helpful to be able to run apps concurrently written in successive
56
+ versions of Rails to aid migration, e.g. run Rails 4.2 and 5.0 variants
57
+ of your application at the same time to carry out A/B testing.
58
+
59
+ To do this serialization formats need to be cross compatible and the
60
+ change in 3aa26cf didn't meet this criteria because the Psych loader
61
+ checks for the existence of `init_with` before setting the instance
62
+ variables and the wrapping behavior of `ActiveSupport::TimeWithZone`
63
+ tries to see if the `Time` instance responds to `init_with` before the
64
+ `@time` variable is set.
65
+
66
+ To fix this we backported just the `init_with` behavior from the change
67
+ in 3aa26cf. If the revived instance is then written out to YAML again
68
+ it will revert to the default Rails 4.2 behavior of converting it to
69
+ a UTC timestamp string.
70
+
71
+ Fixes #26296.
72
+
73
+ *Andrew White*
74
+
75
+ * Fix `ActiveSupport::TimeWithZone#in` across DST boundaries.
76
+
77
+ Previously calls to `in` were being sent to the non-DST aware
78
+ method `Time#since` via `method_missing`. It is now aliased to
79
+ the DST aware `ActiveSupport::TimeWithZone#since` which handles
80
+ transitions across DST boundaries, e.g:
81
+
82
+ Time.zone = "US/Eastern"
83
+
84
+ t = Time.zone.local(2016,11,6,1)
85
+ # => Sun, 06 Nov 2016 01:00:00 EDT -05:00
86
+
87
+ t.in(1.hour)
88
+ # => Sun, 06 Nov 2016 01:00:00 EST -05:00
89
+
90
+ Fixes #26580.
91
+
92
+ *Thomas Balthazar*
93
+
94
+
1
95
  ## Rails 4.2.7 (July 12, 2016) ##
2
96
 
3
97
  * Fixed `ActiveSupport::Logger.broadcast` so that calls to `#silence` now
@@ -26,6 +26,7 @@ require "active_support/dependencies/autoload"
26
26
  require "active_support/version"
27
27
  require "active_support/logger"
28
28
  require "active_support/lazy_load_hooks"
29
+ require "active_support/core_ext/date_and_time/compatibility"
29
30
 
30
31
  module ActiveSupport
31
32
  extend ActiveSupport::Autoload
@@ -80,6 +81,14 @@ module ActiveSupport
80
81
  def self.test_order # :nodoc:
81
82
  @@test_order
82
83
  end
84
+
85
+ def self.to_time_preserves_timezone
86
+ DateAndTime::Compatibility.preserve_timezone
87
+ end
88
+
89
+ def self.to_time_preserves_timezone=(value)
90
+ DateAndTime::Compatibility.preserve_timezone = value
91
+ end
83
92
  end
84
93
 
85
94
  autoload :I18n, "active_support/i18n"
@@ -67,7 +67,7 @@ module ActiveSupport
67
67
  options = names.extract_options!
68
68
  options = merged_options(options)
69
69
  keys_to_names = Hash[names.map{|name| [escape_key(namespaced_key(name, options)), name]}]
70
- raw_values = @data.get_multi(keys_to_names.keys, :raw => true)
70
+ raw_values = @data.get_multi(keys_to_names.keys)
71
71
  values = {}
72
72
  raw_values.each do |key, value|
73
73
  entry = deserialize_entry(value)
@@ -25,8 +25,6 @@ class Class
25
25
 
26
26
  # Returns an array with the direct children of +self+.
27
27
  #
28
- # Integer.subclasses # => [Fixnum, Bignum]
29
- #
30
28
  # class Foo; end
31
29
  # class Bar < Foo; end
32
30
  # class Baz < Bar; end
@@ -0,0 +1,29 @@
1
+ require 'active_support/core_ext/module/attribute_accessors'
2
+ require 'active_support/core_ext/module/remove_method'
3
+
4
+ module DateAndTime
5
+ module Compatibility
6
+ # If true, +to_time+ preserves the timezone offset of receiver.
7
+ #
8
+ # NOTE: With Ruby 2.4+ the default for +to_time+ changed from
9
+ # converting to the local system time, to preserving the offset
10
+ # of the receiver. For backwards compatibility we're overriding
11
+ # this behavior, but new apps will have an initializer that sets
12
+ # this to true, because the new behavior is preferred.
13
+ mattr_accessor(:preserve_timezone, instance_writer: false) { false }
14
+
15
+ def self.included(base)
16
+ base.class_eval do
17
+ remove_possible_method :to_time
18
+
19
+ def to_time
20
+ if preserve_timezone
21
+ @_to_time_with_instance_offset ||= getlocal(utc_offset)
22
+ else
23
+ @_to_time_with_system_offset ||= getlocal
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,4 +1,5 @@
1
1
  require 'active_support/core_ext/date_time/acts_like'
2
2
  require 'active_support/core_ext/date_time/calculations'
3
+ require 'active_support/core_ext/date_time/compatibility'
3
4
  require 'active_support/core_ext/date_time/conversions'
4
5
  require 'active_support/core_ext/date_time/zones'
@@ -24,6 +24,13 @@ class DateTime
24
24
  end_of_day.to_i - to_i
25
25
  end
26
26
 
27
+ # Returns the fraction of a second as a +Rational+
28
+ #
29
+ # DateTime.new(2012, 8, 29, 0, 0, 0.5).subsec # => (1/2)
30
+ def subsec
31
+ sec_fraction
32
+ end
33
+
27
34
  # Returns a new DateTime where one or more of the elements have been changed
28
35
  # according to the +options+ parameter. The time options (<tt>:hour</tt>,
29
36
  # <tt>:min</tt>, <tt>:sec</tt>) reset cascadingly, so if only the hour is
@@ -139,14 +146,32 @@ class DateTime
139
146
  end
140
147
  alias :at_end_of_minute :end_of_minute
141
148
 
142
- # Adjusts DateTime to UTC by adding its offset value; offset is set to 0.
149
+ # Returns a <tt>Time</tt> instance of the simultaneous time in the system timezone.
150
+ def localtime(utc_offset = nil)
151
+ utc = new_offset(0)
152
+
153
+ Time.utc(
154
+ utc.year, utc.month, utc.day,
155
+ utc.hour, utc.min, utc.sec + utc.sec_fraction
156
+ ).getlocal(utc_offset)
157
+ end
158
+ alias_method :getlocal, :localtime
159
+
160
+ # Returns a <tt>Time</tt> instance of the simultaneous time in the UTC timezone.
143
161
  #
144
162
  # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)) # => Mon, 21 Feb 2005 10:11:12 -0600
145
- # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc # => Mon, 21 Feb 2005 16:11:12 +0000
163
+ # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc # => Mon, 21 Feb 2005 16:11:12 UTC
146
164
  def utc
147
- new_offset(0)
165
+ utc = new_offset(0)
166
+
167
+ Time.utc(
168
+ utc.year, utc.month, utc.day,
169
+ utc.hour, utc.min, utc.sec + utc.sec_fraction
170
+ )
148
171
  end
172
+ alias_method :getgm, :utc
149
173
  alias_method :getutc, :utc
174
+ alias_method :gmtime, :utc
150
175
 
151
176
  # Returns +true+ if <tt>offset == 0</tt>.
152
177
  def utc?
@@ -0,0 +1,5 @@
1
+ require 'active_support/core_ext/date_and_time/compatibility'
2
+
3
+ class DateTime
4
+ include DateAndTime::Compatibility
5
+ end
@@ -78,3 +78,19 @@ class Range #:nodoc:
78
78
  end
79
79
  end
80
80
  end
81
+
82
+ # Array#sum was added in Ruby 2.4 but it only works with Numeric elements.
83
+ #
84
+ # We tried shimming it to attempt the fast native method, rescue TypeError,
85
+ # and fall back to the compatible implementation, but that's much slower than
86
+ # just calling the compat method in the first place.
87
+ if Array.instance_methods(false).include?(:sum) && !(%w[a].sum rescue false)
88
+ class Array
89
+ remove_method :sum
90
+
91
+ def sum(*args) #:nodoc:
92
+ # Use Enumerable#sum instead.
93
+ super
94
+ end
95
+ end
96
+ end
@@ -1,20 +1,24 @@
1
1
  class Hash
2
- # Returns a hash with non +nil+ values.
3
- #
4
- # hash = { a: true, b: false, c: nil}
5
- # hash.compact # => { a: true, b: false}
6
- # hash # => { a: true, b: false, c: nil}
7
- # { c: nil }.compact # => {}
8
- def compact
9
- self.select { |_, value| !value.nil? }
2
+ unless Hash.instance_methods(false).include?(:compact)
3
+ # Returns a hash with non +nil+ values.
4
+ #
5
+ # hash = { a: true, b: false, c: nil}
6
+ # hash.compact # => { a: true, b: false}
7
+ # hash # => { a: true, b: false, c: nil}
8
+ # { c: nil }.compact # => {}
9
+ def compact
10
+ self.select { |_, value| !value.nil? }
11
+ end
10
12
  end
11
13
 
12
- # Replaces current hash with non +nil+ values.
13
- #
14
- # hash = { a: true, b: false, c: nil}
15
- # hash.compact! # => { a: true, b: false}
16
- # hash # => { a: true, b: false}
17
- def compact!
18
- self.reject! { |_, value| value.nil? }
14
+ unless Hash.instance_methods(false).include?(:compact!)
15
+ # Replaces current hash with non +nil+ values.
16
+ #
17
+ # hash = { a: true, b: false, c: nil}
18
+ # hash.compact! # => { a: true, b: false}
19
+ # hash # => { a: true, b: false}
20
+ def compact!
21
+ self.reject! { |_, value| value.nil? }
22
+ end
19
23
  end
20
24
  end
@@ -55,8 +55,7 @@ class Hash
55
55
  #
56
56
  # XML_TYPE_NAMES = {
57
57
  # "Symbol" => "symbol",
58
- # "Fixnum" => "integer",
59
- # "Bignum" => "integer",
58
+ # "Integer" => "integer",
60
59
  # "BigDecimal" => "decimal",
61
60
  # "Float" => "float",
62
61
  # "TrueClass" => "boolean",
@@ -11,7 +11,7 @@ class Hash
11
11
  result[key] = yield(value)
12
12
  end
13
13
  result
14
- end
14
+ end unless method_defined? :transform_values
15
15
 
16
16
  # Destructive +transform_values+
17
17
  def transform_values!
@@ -19,5 +19,5 @@ class Hash
19
19
  each do |key, value|
20
20
  self[key] = yield(value)
21
21
  end
22
- end
22
+ end unless method_defined? :transform_values!
23
23
  end
@@ -118,7 +118,15 @@ class Numeric
118
118
  end
119
119
  end
120
120
 
121
- [Float, Fixnum, Bignum, BigDecimal].each do |klass|
121
+ klasses = [Float, BigDecimal]
122
+ # Ruby 2.4+ unifies Fixnum & Bignum into Integer.
123
+ if 0.class == Integer
124
+ klasses << Integer
125
+ else
126
+ klasses << Fixnum << Bignum
127
+ end
128
+
129
+ klasses.each do |klass|
122
130
  klass.send(:alias_method, :to_default_s, :to_s)
123
131
 
124
132
  klass.send(:define_method, :to_s) do |*args|
@@ -1,7 +1,7 @@
1
1
  #--
2
- # Most objects are cloneable, but not all. For example you can't dup +nil+:
2
+ # Most objects are cloneable, but not all. For example you can't dup methods:
3
3
  #
4
- # nil.dup # => TypeError: can't dup NilClass
4
+ # method(:puts).dup # => TypeError: allocator undefined for Method
5
5
  #
6
6
  # Classes may signal their instances are not duplicable removing +dup+/+clone+
7
7
  # or raising exceptions from them. So, to dup an arbitrary object you normally
@@ -27,52 +27,78 @@ class Object
27
27
  end
28
28
 
29
29
  class NilClass
30
- # +nil+ is not duplicable:
31
- #
32
- # nil.duplicable? # => false
33
- # nil.dup # => TypeError: can't dup NilClass
34
- def duplicable?
35
- false
30
+ begin
31
+ nil.dup
32
+ rescue TypeError
33
+
34
+ # +nil+ is not duplicable:
35
+ #
36
+ # nil.duplicable? # => false
37
+ # nil.dup # => TypeError: can't dup NilClass
38
+ def duplicable?
39
+ false
40
+ end
36
41
  end
37
42
  end
38
43
 
39
44
  class FalseClass
40
- # +false+ is not duplicable:
41
- #
42
- # false.duplicable? # => false
43
- # false.dup # => TypeError: can't dup FalseClass
44
- def duplicable?
45
- false
45
+ begin
46
+ false.dup
47
+ rescue TypeError
48
+
49
+ # +false+ is not duplicable:
50
+ #
51
+ # false.duplicable? # => false
52
+ # false.dup # => TypeError: can't dup FalseClass
53
+ def duplicable?
54
+ false
55
+ end
46
56
  end
47
57
  end
48
58
 
49
59
  class TrueClass
50
- # +true+ is not duplicable:
51
- #
52
- # true.duplicable? # => false
53
- # true.dup # => TypeError: can't dup TrueClass
54
- def duplicable?
55
- false
60
+ begin
61
+ true.dup
62
+ rescue TypeError
63
+
64
+ # +true+ is not duplicable:
65
+ #
66
+ # true.duplicable? # => false
67
+ # true.dup # => TypeError: can't dup TrueClass
68
+ def duplicable?
69
+ false
70
+ end
56
71
  end
57
72
  end
58
73
 
59
74
  class Symbol
60
- # Symbols are not duplicable:
61
- #
62
- # :my_symbol.duplicable? # => false
63
- # :my_symbol.dup # => TypeError: can't dup Symbol
64
- def duplicable?
65
- false
75
+ begin
76
+ :symbol.dup # Ruby 2.4.x.
77
+ 'symbol_from_string'.to_sym.dup # Some symbols can't `dup` in Ruby 2.4.0.
78
+ rescue TypeError
79
+
80
+ # Symbols are not duplicable:
81
+ #
82
+ # :my_symbol.duplicable? # => false
83
+ # :my_symbol.dup # => TypeError: can't dup Symbol
84
+ def duplicable?
85
+ false
86
+ end
66
87
  end
67
88
  end
68
89
 
69
90
  class Numeric
70
- # Numbers are not duplicable:
71
- #
72
- # 3.duplicable? # => false
73
- # 3.dup # => TypeError: can't dup Fixnum
74
- def duplicable?
75
- false
91
+ begin
92
+ 1.dup
93
+ rescue TypeError
94
+
95
+ # Numbers are not duplicable:
96
+ #
97
+ # 3.duplicable? # => false
98
+ # 3.dup # => TypeError: can't dup Integer
99
+ def duplicable?
100
+ false
101
+ end
76
102
  end
77
103
  end
78
104
 
@@ -1,5 +1,5 @@
1
1
  class String
2
- # If you pass a single Fixnum, returns a substring of one character at that
2
+ # If you pass a single integer, returns a substring of one character at that
3
3
  # position. The first character of the string is at position 0, the next at
4
4
  # position 1, and so on. If a range is supplied, a substring containing
5
5
  # characters at offsets given by the range is returned. In both cases, if an
@@ -31,7 +31,7 @@ class String
31
31
  parts.fetch(:offset, form == :utc ? 0 : nil)
32
32
  )
33
33
 
34
- form == :utc ? time.utc : time.getlocal
34
+ form == :utc ? time.utc : time.to_time
35
35
  end
36
36
 
37
37
  # Converts a string to a Date value.
@@ -1,5 +1,6 @@
1
1
  require 'active_support/core_ext/time/acts_like'
2
2
  require 'active_support/core_ext/time/calculations'
3
+ require 'active_support/core_ext/time/compatibility'
3
4
  require 'active_support/core_ext/time/conversions'
4
5
  require 'active_support/core_ext/time/marshal'
5
6
  require 'active_support/core_ext/time/zones'
@@ -63,6 +63,13 @@ class Time
63
63
  end_of_day.to_i - to_i
64
64
  end
65
65
 
66
+ # Returns the fraction of a second as a +Rational+
67
+ #
68
+ # Time.new(2012, 8, 29, 0, 0, 0.5).sec_fraction # => (1/2)
69
+ def sec_fraction
70
+ subsec
71
+ end
72
+
66
73
  # Returns a new Time where one or more of the elements have been changed according
67
74
  # to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
68
75
  # <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
@@ -0,0 +1,5 @@
1
+ require 'active_support/core_ext/date_and_time/compatibility'
2
+
3
+ class Time
4
+ include DateAndTime::Compatibility
5
+ end
@@ -7,8 +7,8 @@ module ActiveSupport
7
7
  module VERSION
8
8
  MAJOR = 4
9
9
  MINOR = 2
10
- TINY = 7
11
- PRE = "1"
10
+ TINY = 8
11
+ PRE = "rc1"
12
12
 
13
13
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
14
14
  end
@@ -245,6 +245,11 @@ module ActiveSupport
245
245
  dup.tap { |hash| hash.reject!(*args, &block) }
246
246
  end
247
247
 
248
+ def transform_values(*args, &block)
249
+ return to_enum(:transform_values) unless block_given?
250
+ dup.tap { |hash| hash.transform_values!(*args, &block) }
251
+ end
252
+
248
253
  # Convert to a regular hash with string keys.
249
254
  def to_hash
250
255
  _new_hash = Hash.new
@@ -18,6 +18,8 @@ module ActiveSupport
18
18
  # encrypted_data = crypt.encrypt_and_sign('my secret data') # => "NlFBTTMwOUV5UlA1QlNEN2xkY2d6eThYWWh..."
19
19
  # crypt.decrypt_and_verify(encrypted_data) # => "my secret data"
20
20
  class MessageEncryptor
21
+ DEFAULT_CIPHER = "aes-256-cbc"
22
+
21
23
  module NullSerializer #:nodoc:
22
24
  def self.load(value)
23
25
  value
@@ -64,6 +66,11 @@ module ActiveSupport
64
66
  _decrypt(verifier.verify(value))
65
67
  end
66
68
 
69
+ # Given a cipher, returns the key length of the cipher to help generate the key of desired size
70
+ def self.key_len(cipher = DEFAULT_CIPHER)
71
+ OpenSSL::Cipher.new(cipher).key_len
72
+ end
73
+
67
74
  private
68
75
 
69
76
  def _encrypt(value)
@@ -97,7 +104,7 @@ module ActiveSupport
97
104
  end
98
105
 
99
106
  def new_cipher
100
- OpenSSL::Cipher::Cipher.new(@cipher)
107
+ OpenSSL::Cipher.new(@cipher)
101
108
  end
102
109
 
103
110
  def verifier
@@ -7,7 +7,7 @@ module ActiveSupport
7
7
  @stubs = {}
8
8
  end
9
9
 
10
- def stub_object(object, method_name, return_value)
10
+ def stub_object(object, method_name, &block)
11
11
  key = [object.object_id, method_name]
12
12
 
13
13
  if stub = @stubs[key]
@@ -19,7 +19,7 @@ module ActiveSupport
19
19
  @stubs[key] = Stub.new(object, method_name, new_name)
20
20
 
21
21
  object.singleton_class.send :alias_method, new_name, method_name
22
- object.define_singleton_method(method_name) { return_value }
22
+ object.define_singleton_method(method_name, &block)
23
23
  end
24
24
 
25
25
  def unstub_all!
@@ -97,8 +97,9 @@ module ActiveSupport
97
97
  now = date_or_time.to_time.change(usec: 0)
98
98
  end
99
99
 
100
- simple_stubs.stub_object(Time, :now, now)
101
- simple_stubs.stub_object(Date, :today, now.to_date)
100
+ simple_stubs.stub_object(Time, :now) { at(now.to_i) }
101
+ simple_stubs.stub_object(Date, :today) { jd(now.to_date.jd) }
102
+ simple_stubs.stub_object(DateTime, :now) { jd(now.to_date.jd, now.hour, now.min, now.sec, Rational(now.utc_offset, 86400)) }
102
103
 
103
104
  if block_given?
104
105
  begin
@@ -1,5 +1,6 @@
1
1
  require 'active_support/values/time_zone'
2
2
  require 'active_support/core_ext/object/acts_like'
3
+ require 'active_support/core_ext/date_and_time/compatibility'
3
4
 
4
5
  module ActiveSupport
5
6
  # A Time-like class that can represent a time in any time zone. Necessary
@@ -40,20 +41,21 @@ module ActiveSupport
40
41
  'Time'
41
42
  end
42
43
 
43
- include Comparable
44
+ include Comparable, DateAndTime::Compatibility
44
45
  attr_reader :time_zone
45
46
 
46
47
  def initialize(utc_time, time_zone, local_time = nil, period = nil)
47
- @utc, @time_zone, @time = utc_time, time_zone, local_time
48
+ @utc = utc_time ? transfer_time_values_to_utc_constructor(utc_time) : nil
49
+ @time_zone, @time = time_zone, local_time
48
50
  @period = @utc ? period : get_period_and_ensure_valid_local_time(period)
49
51
  end
50
52
 
51
- # Returns a Time or DateTime instance that represents the time in +time_zone+.
53
+ # Returns a <tt>Time</tt> instance that represents the time in +time_zone+.
52
54
  def time
53
55
  @time ||= period.to_local(@utc)
54
56
  end
55
57
 
56
- # Returns a Time or DateTime instance that represents the time in UTC.
58
+ # Returns a <tt>Time</tt> instance of the simultaneous time in the UTC timezone.
57
59
  def utc
58
60
  @utc ||= period.to_utc(@time)
59
61
  end
@@ -73,10 +75,9 @@ module ActiveSupport
73
75
  utc.in_time_zone(new_zone)
74
76
  end
75
77
 
76
- # Returns a <tt>Time.local()</tt> instance of the simultaneous time in your
77
- # system's <tt>ENV['TZ']</tt> zone.
78
+ # Returns a <tt>Time</tt> instance of the simultaneous time in the system timezone.
78
79
  def localtime(utc_offset = nil)
79
- utc.respond_to?(:getlocal) ? utc.getlocal(utc_offset) : utc.to_time.getlocal(utc_offset)
80
+ utc.getlocal(utc_offset)
80
81
  end
81
82
  alias_method :getlocal, :localtime
82
83
 
@@ -160,7 +161,11 @@ module ActiveSupport
160
161
  end
161
162
  end
162
163
 
163
- def encode_with(coder)
164
+ def init_with(coder) #:nodoc:
165
+ initialize(coder['utc'], coder['zone'], coder['time'])
166
+ end
167
+
168
+ def encode_with(coder) #:nodoc:
164
169
  if coder.respond_to?(:represent_object)
165
170
  coder.represent_object(nil, utc)
166
171
  else
@@ -276,6 +281,7 @@ module ActiveSupport
276
281
  utc.since(other).in_time_zone(time_zone)
277
282
  end
278
283
  end
284
+ alias_method :in, :since
279
285
 
280
286
  def ago(other)
281
287
  since(-other)
@@ -316,13 +322,8 @@ module ActiveSupport
316
322
  utc.to_r
317
323
  end
318
324
 
319
- # Return an instance of Time in the system timezone.
320
- def to_time
321
- utc.to_time
322
- end
323
-
324
325
  def to_datetime
325
- utc.to_datetime.new_offset(Rational(utc_offset, 86_400))
326
+ @to_datetime ||= utc.to_datetime.new_offset(Rational(utc_offset, 86_400))
326
327
  end
327
328
 
328
329
  # So that +self+ <tt>acts_like?(:time)</tt>.
@@ -360,7 +361,6 @@ module ActiveSupport
360
361
  # Ensure proxy class responds to all methods that underlying time instance
361
362
  # responds to.
362
363
  def respond_to_missing?(sym, include_priv)
363
- # consistently respond false to acts_like?(:date), regardless of whether #time is a Time or DateTime
364
364
  return false if sym.to_sym == :acts_like_date?
365
365
  time.respond_to?(sym, include_priv)
366
366
  end
@@ -388,7 +388,7 @@ module ActiveSupport
388
388
  end
389
389
 
390
390
  def transfer_time_values_to_utc_constructor(time)
391
- ::Time.utc(time.year, time.month, time.day, time.hour, time.min, time.sec, Rational(time.nsec, 1000))
391
+ ::Time.utc(time.year, time.month, time.day, time.hour, time.min, time.sec + time.subsec)
392
392
  end
393
393
 
394
394
  def duration_of_variable_length?(obj)
@@ -273,6 +273,10 @@ module ActiveSupport
273
273
  @tzinfo = tzinfo || TimeZone.find_tzinfo(name)
274
274
  end
275
275
 
276
+ def init_with(coder) #:nodoc:
277
+ initialize(coder['name'])
278
+ end
279
+
276
280
  # Returns the offset of this time zone from UTC in seconds.
277
281
  def utc_offset
278
282
  if @utc_offset
@@ -32,20 +32,25 @@ module ActiveSupport
32
32
  "binary" => "base64"
33
33
  } unless defined?(DEFAULT_ENCODINGS)
34
34
 
35
- TYPE_NAMES = {
36
- "Symbol" => "symbol",
37
- "Fixnum" => "integer",
38
- "Bignum" => "integer",
39
- "BigDecimal" => "decimal",
40
- "Float" => "float",
41
- "TrueClass" => "boolean",
42
- "FalseClass" => "boolean",
43
- "Date" => "date",
44
- "DateTime" => "dateTime",
45
- "Time" => "dateTime",
46
- "Array" => "array",
47
- "Hash" => "hash"
48
- } unless defined?(TYPE_NAMES)
35
+ unless defined?(TYPE_NAMES)
36
+ TYPE_NAMES = {
37
+ "Symbol" => "symbol",
38
+ "Integer" => "integer",
39
+ "BigDecimal" => "decimal",
40
+ "Float" => "float",
41
+ "TrueClass" => "boolean",
42
+ "FalseClass" => "boolean",
43
+ "Date" => "date",
44
+ "DateTime" => "dateTime",
45
+ "Time" => "dateTime",
46
+ "Array" => "array",
47
+ "Hash" => "hash"
48
+ }
49
+
50
+ # No need to map these on Ruby 2.4+
51
+ TYPE_NAMES["Fixnum"] = "integer" unless 0.class == Integer
52
+ TYPE_NAMES["Bignum"] = "integer" unless 0.class == Integer
53
+ end
49
54
 
50
55
  FORMATTING = {
51
56
  "symbol" => Proc.new { |symbol| symbol.to_s },
@@ -63,7 +68,17 @@ module ActiveSupport
63
68
  "datetime" => Proc.new { |time| Time.xmlschema(time).utc rescue ::DateTime.parse(time).utc },
64
69
  "integer" => Proc.new { |integer| integer.to_i },
65
70
  "float" => Proc.new { |float| float.to_f },
66
- "decimal" => Proc.new { |number| BigDecimal(number) },
71
+ "decimal" => Proc.new do |number|
72
+ if String === number
73
+ begin
74
+ BigDecimal(number)
75
+ rescue ArgumentError
76
+ BigDecimal('0')
77
+ end
78
+ else
79
+ BigDecimal(number)
80
+ end
81
+ end,
67
82
  "boolean" => Proc.new { |boolean| %w(1 true).include?(boolean.to_s.strip) },
68
83
  "string" => Proc.new { |string| string.to_s },
69
84
  "yaml" => Proc.new { |yaml| YAML::load(yaml) rescue yaml },
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activesupport
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.2.7.1
4
+ version: 4.2.8.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-10 00:00:00.000000000 Z
11
+ date: 2017-02-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: i18n
@@ -24,26 +24,6 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.7'
27
- - !ruby/object:Gem::Dependency
28
- name: json
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '1.7'
34
- - - ">="
35
- - !ruby/object:Gem::Version
36
- version: 1.7.7
37
- type: :runtime
38
- prerelease: false
39
- version_requirements: !ruby/object:Gem::Requirement
40
- requirements:
41
- - - "~>"
42
- - !ruby/object:Gem::Version
43
- version: '1.7'
44
- - - ">="
45
- - !ruby/object:Gem::Version
46
- version: 1.7.7
47
27
  - !ruby/object:Gem::Dependency
48
28
  name: tzinfo
49
29
  requirement: !ruby/object:Gem::Requirement
@@ -142,10 +122,12 @@ files:
142
122
  - lib/active_support/core_ext/date/conversions.rb
143
123
  - lib/active_support/core_ext/date/zones.rb
144
124
  - lib/active_support/core_ext/date_and_time/calculations.rb
125
+ - lib/active_support/core_ext/date_and_time/compatibility.rb
145
126
  - lib/active_support/core_ext/date_and_time/zones.rb
146
127
  - lib/active_support/core_ext/date_time.rb
147
128
  - lib/active_support/core_ext/date_time/acts_like.rb
148
129
  - lib/active_support/core_ext/date_time/calculations.rb
130
+ - lib/active_support/core_ext/date_time/compatibility.rb
149
131
  - lib/active_support/core_ext/date_time/conversions.rb
150
132
  - lib/active_support/core_ext/date_time/zones.rb
151
133
  - lib/active_support/core_ext/digest/uuid.rb
@@ -231,6 +213,7 @@ files:
231
213
  - lib/active_support/core_ext/time.rb
232
214
  - lib/active_support/core_ext/time/acts_like.rb
233
215
  - lib/active_support/core_ext/time/calculations.rb
216
+ - lib/active_support/core_ext/time/compatibility.rb
234
217
  - lib/active_support/core_ext/time/conversions.rb
235
218
  - lib/active_support/core_ext/time/marshal.rb
236
219
  - lib/active_support/core_ext/time/zones.rb
@@ -335,15 +318,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
335
318
  version: 1.9.3
336
319
  required_rubygems_version: !ruby/object:Gem::Requirement
337
320
  requirements:
338
- - - ">="
321
+ - - ">"
339
322
  - !ruby/object:Gem::Version
340
- version: '0'
323
+ version: 1.3.1
341
324
  requirements: []
342
325
  rubyforge_project:
343
- rubygems_version: 2.6.6
326
+ rubygems_version: 2.6.10
344
327
  signing_key:
345
328
  specification_version: 4
346
329
  summary: A toolkit of support libraries and Ruby core extensions extracted from the
347
330
  Rails framework.
348
331
  test_files: []
349
- has_rdoc: