timecop 0.9.6 → 0.9.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c86a01ea95f5019cb15a6a66c5668e68e7f1e293ca14b910a10cbe1cdd70d668
4
- data.tar.gz: e5c6987d3a452fa9ead841021f93bf4ea6bac713c1f6cea38cfc1c1d49baf6ee
3
+ metadata.gz: 5ffc3899071434ff0ae8eb0a9e4a6ea4c2d8794547113c272bdc24a384d2eb45
4
+ data.tar.gz: e9333e4c2cf362558c432d7b954a724ff588e66c4dcce8d3af4a327dd6dcb894
5
5
  SHA512:
6
- metadata.gz: 4abbcd2d37b9fdf6dfb1ed1f63f945a882cd62a47ae2ae237da003ccac0bc660572be0800933ea484fb1632707bdc2de457b96f9aad8a62b1dfd96d766220692
7
- data.tar.gz: a19cc9026478a29161a832454edebf76105d56d3841575af71e9dbaa305a40a68af285d17b7473369ae913e463cadd7b67ab2e099d13d3162b713d2c3cd87d05
6
+ metadata.gz: 692759ecf208cccb83f72d2cd2a3632d6fb6477e9ac1dbf1ca19d8c23a0b864093abdfdc1d51ee98078858dc2dd3eab50f1bd8b469cc84f0619c99bed242169f
7
+ data.tar.gz: 85fc3b65a8f415601a047d4189ff497a73f49d4d48647881a6579d82dc6f12ab9e6a088da0ca2b3c2a25693f220ce3c8f31b5f2847f6a5d4784c63ace77136ff
data/README.markdown CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  ## DESCRIPTION
7
7
 
8
- A gem providing "time travel" and "time freezing" capabilities, making it dead simple to test time-dependent code. It provides a unified method to mock Time.now, Date.today, and DateTime.now in a single call.
8
+ A gem providing "time travel" and "time freezing" capabilities, making it dead simple to test time-dependent code. It provides a unified method to mock `Time.now`, `Date.today`, `DateTime.now`, and `Process.clock_gettime` in a single call.
9
9
 
10
10
  ## INSTALL
11
11
 
@@ -17,13 +17,13 @@ A gem providing "time travel" and "time freezing" capabilities, making it dead s
17
17
  - Travel back to a specific point in time, but allow time to continue moving forward from there.
18
18
  - Scale time by a given scaling factor that will cause time to move at an accelerated pace.
19
19
  - No dependencies, can be used with _any_ ruby project
20
- - Timecop api allows arguments to be passed into #freeze and #travel as one of the following:
20
+ - Timecop api allows arguments to be passed into `#freeze` and `#travel` as one of the following:
21
21
  - Time instance
22
22
  - DateTime instance
23
23
  - Date instance
24
24
  - individual arguments (year, month, day, hour, minute, second)
25
- - a single integer argument that is interpreted as an offset in seconds from Time.now
26
- - Nested calls to Timecop#travel and Timecop#freeze are supported -- each block will maintain its interpretation of now.
25
+ - a single integer argument that is interpreted as an offset in seconds from `Time.now`
26
+ - Nested calls to `Timecop#travel` and `Timecop#freeze` are supported -- each block will maintain its interpretation of now.
27
27
  - Works with regular Ruby projects, and Ruby on Rails projects
28
28
 
29
29
  ## USAGE
@@ -62,7 +62,7 @@ helpful if your whole application is time-sensitive. It allows you to build
62
62
  your test data at a single point in time, and to move in/out of that time as
63
63
  appropriate (within your tests)
64
64
 
65
- in config/environments/test.rb
65
+ in `config/environments/test.rb`
66
66
 
67
67
  ```ruby
68
68
  config.after_initialize do
@@ -74,10 +74,10 @@ end
74
74
 
75
75
  ### The difference between Timecop.freeze and Timecop.travel
76
76
 
77
- freeze is used to statically mock the concept of now. As your program executes,
78
- Time.now will not change unless you make subsequent calls into the Timecop API.
79
- travel, on the other hand, computes an offset between what we currently think
80
- Time.now is (recall that we support nested traveling) and the time passed in.
77
+ `freeze` is used to statically mock the concept of now. As your program executes,
78
+ `Time.now` will not change unless you make subsequent calls into the Timecop API.
79
+ `travel`, on the other hand, computes an offset between what we currently think
80
+ `Time.now` is (recall that we support nested traveling) and the time passed in.
81
81
  It uses this offset to simulate the passage of time. To demonstrate, consider
82
82
  the following code snippets:
83
83
 
@@ -50,21 +50,28 @@ class Date #:nodoc:
50
50
 
51
51
  d = Date._strptime(str, fmt)
52
52
  now = Time.now.to_date
53
- year = d[:year] || now.year
53
+ year = d[:year] || d[:cwyear] || now.year
54
54
  mon = d[:mon] || now.mon
55
55
  if d.keys == [:year]
56
56
  Date.new(year, 1, 1, start)
57
57
  elsif d[:mday]
58
58
  Date.new(year, mon, d[:mday], start)
59
- elsif d[:wday]
60
- Date.new(year, mon, now.mday, start) + (d[:wday] - now.wday)
61
59
  elsif d[:yday]
62
60
  Date.new(year, 1, 1, start).next_day(d[:yday] - 1)
63
- elsif d[:cwyear] && d[:cweek]
64
- if d[:cwday]
65
- Date.commercial(d[:cwyear], d[:cweek], d[:cwday], start)
66
- else
67
- Date.commercial(d[:cwyear], d[:cweek], 1, start)
61
+ elsif d[:cwyear] || d[:cweek] || d[:wnum0] || d[:wnum1] || d[:wday] || d[:cwday]
62
+ week = d[:cweek] || d[:wnum1] || d[:wnum0] || now.strftime('%W').to_i
63
+ if d[:wnum0] #Week of year where week starts on sunday
64
+ if d[:cwday] #monday based day of week
65
+ Date.strptime_without_mock_date("#{year} #{week} #{d[:cwday]}", '%Y %U %u', start)
66
+ else
67
+ Date.strptime_without_mock_date("#{year} #{week} #{d[:wday] || 0}", '%Y %U %w', start)
68
+ end
69
+ else #Week of year where week starts on monday
70
+ if d[:wday] #sunday based day of week
71
+ Date.strptime_without_mock_date("#{year} #{week} #{d[:wday]}", '%Y %W %w', start)
72
+ else
73
+ Date.strptime_without_mock_date("#{year} #{week} #{d[:cwday] || 1}", '%Y %W %u', start)
74
+ end
68
75
  end
69
76
  elsif d[:seconds]
70
77
  Time.at(d[:seconds]).to_date
@@ -125,7 +132,6 @@ class DateTime #:nodoc:
125
132
  alias_method :now, :now_with_mock_time
126
133
 
127
134
  def parse_with_mock_date(*args)
128
- date_hash = Date._parse(*args)
129
135
  parsed_date = parse_without_mock_date(*args)
130
136
  return parsed_date unless mocked_time_stack_item
131
137
  date_hash = DateTime._parse(*args)
@@ -137,8 +143,17 @@ class DateTime #:nodoc:
137
143
  DateTime.new(mocked_time_stack_item.year, date_hash[:mon], date_hash[:mday])
138
144
  when date_hash[:mday]
139
145
  DateTime.new(mocked_time_stack_item.year, mocked_time_stack_item.month, date_hash[:mday])
146
+ when date_hash[:wday] && date_hash[:hour] && date_hash[:min]
147
+ closest_date = Date.closest_wday(date_hash[:wday]).to_datetime
148
+
149
+ DateTime.new(
150
+ closest_date.year, closest_date.month, closest_date.day,
151
+ date_hash[:hour], date_hash[:min]
152
+ )
140
153
  when date_hash[:wday]
141
154
  Date.closest_wday(date_hash[:wday]).to_datetime
155
+ when date_hash[:hour] && date_hash[:min] && date_hash[:sec]
156
+ DateTime.new(mocked_time_stack_item.year, mocked_time_stack_item.month, mocked_time_stack_item.day, date_hash[:hour], date_hash[:min], date_hash[:sec])
142
157
  else
143
158
  parsed_date + mocked_time_stack_item.travel_offset_days
144
159
  end
@@ -152,3 +167,59 @@ class DateTime #:nodoc:
152
167
  end
153
168
  end
154
169
  end
170
+
171
+ if RUBY_VERSION >= '2.1.0'
172
+ module Process #:nodoc:
173
+ class << self
174
+ alias_method :clock_gettime_without_mock, :clock_gettime
175
+
176
+ def clock_gettime_mock_time(clock_id, unit = :float_second)
177
+ mock_time = case clock_id
178
+ when Process::CLOCK_MONOTONIC
179
+ mock_time_monotonic
180
+ when Process::CLOCK_REALTIME
181
+ mock_time_realtime
182
+ end
183
+
184
+ return clock_gettime_without_mock(clock_id, unit) unless mock_time
185
+
186
+ divisor = case unit
187
+ when :float_second
188
+ 1_000_000_000.0
189
+ when :second
190
+ 1_000_000_000
191
+ when :float_millisecond
192
+ 1_000_000.0
193
+ when :millisecond
194
+ 1_000_000
195
+ when :float_microsecond
196
+ 1000.0
197
+ when :microsecond
198
+ 1000
199
+ when :nanosecond
200
+ 1
201
+ end
202
+
203
+ (mock_time / divisor)
204
+ end
205
+
206
+ alias_method :clock_gettime, :clock_gettime_mock_time
207
+
208
+ private
209
+
210
+ def mock_time_monotonic
211
+ mocked_time_stack_item = Timecop.top_stack_item
212
+ mocked_time_stack_item.nil? ? nil : mocked_time_stack_item.monotonic
213
+ end
214
+
215
+ def mock_time_realtime
216
+ mocked_time_stack_item = Timecop.top_stack_item
217
+
218
+ return nil if mocked_time_stack_item.nil?
219
+
220
+ t = mocked_time_stack_item.time
221
+ t.to_i * 1_000_000_000 + t.nsec
222
+ end
223
+ end
224
+ end
225
+ end
@@ -9,6 +9,7 @@ class Timecop
9
9
  @travel_offset = @scaling_factor = nil
10
10
  @scaling_factor = args.shift if mock_type == :scale
11
11
  @mock_type = mock_type
12
+ @monotonic = parse_monotonic_time(*args) if RUBY_VERSION >= '2.1.0'
12
13
  @time = parse_time(*args)
13
14
  @time_was = Time.now_without_mock_time
14
15
  @travel_offset = compute_travel_offset
@@ -54,6 +55,26 @@ class Timecop
54
55
  @scaling_factor
55
56
  end
56
57
 
58
+ if RUBY_VERSION >= '2.1.0'
59
+ def monotonic
60
+ if travel_offset.nil?
61
+ @monotonic
62
+ elsif scaling_factor.nil?
63
+ current_monotonic + travel_offset * (10 ** 9)
64
+ else
65
+ (@monotonic + (current_monotonic - @monotonic) * scaling_factor).to_i
66
+ end
67
+ end
68
+
69
+ def current_monotonic
70
+ Process.clock_gettime_without_mock(Process::CLOCK_MONOTONIC, :nanosecond)
71
+ end
72
+
73
+ def current_monotonic_with_mock
74
+ Process.clock_gettime_mock_time(Process::CLOCK_MONOTONIC, :nanosecond)
75
+ end
76
+ end
77
+
57
78
  def time(time_klass = Time) #:nodoc:
58
79
  if @time.respond_to?(:in_time_zone)
59
80
  time = time_klass.at(@time.dup.localtime)
@@ -97,6 +118,16 @@ class Timecop
97
118
  Rational(utc_offset, 24 * 60 * 60)
98
119
  end
99
120
 
121
+ def parse_monotonic_time(*args)
122
+ arg = args.shift
123
+ offset_in_nanoseconds = if args.empty? && (arg.kind_of?(Integer) || arg.kind_of?(Float))
124
+ arg * 1_000_000_000
125
+ else
126
+ 0
127
+ end
128
+ current_monotonic_with_mock + offset_in_nanoseconds
129
+ end
130
+
100
131
  def parse_time(*args)
101
132
  arg = args.shift
102
133
  if arg.is_a?(Time)
@@ -38,6 +38,12 @@ class Timecop
38
38
  # previous values after the block has finished executing. This allows us to nest multiple
39
39
  # calls to Timecop.travel and have each block maintain it's concept of "now."
40
40
  #
41
+ # The Process.clock_gettime call mocks both CLOCK::MONOTIC and CLOCK::REALTIME
42
+ #
43
+ # CLOCK::MONOTONIC works slightly differently than other clocks. This clock cannot move to a
44
+ # particular date/time. So the only option that changes this clock is #4 which will move the
45
+ # clock the requested offset. Otherwise the clock is frozen to the current tick.
46
+ #
41
47
  # * Note: Timecop.freeze will actually freeze time. This can cause unanticipated problems if
42
48
  # benchmark or other timing calls are executed, which implicitly expect Time to actually move
43
49
  # forward.
@@ -121,9 +127,19 @@ class Timecop
121
127
  instance.thread_safe
122
128
  end
123
129
 
124
- # Returns whether or not Timecop is currently frozen/travelled
130
+ # Returns whether or not Timecop is currently frozen
125
131
  def frozen?
126
- !instance.stack.empty?
132
+ !instance.stack.empty? && instance.stack.last.mock_type == :freeze
133
+ end
134
+
135
+ # Returns whether or not Timecop is currently travelled
136
+ def travelled?
137
+ !instance.stack.empty? && instance.stack.last.mock_type == :travel
138
+ end
139
+
140
+ # Returns whether or not Timecop is currently scaled
141
+ def scaled?
142
+ !instance.stack.empty? && instance.stack.last.mock_type == :scale
127
143
  end
128
144
 
129
145
  private
@@ -1,3 +1,3 @@
1
1
  class Timecop
2
- VERSION = "0.9.6"
2
+ VERSION = "0.9.9"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timecop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.6
4
+ version: 0.9.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Travis Jeffery
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-11-29 00:00:00.000000000 Z
12
+ date: 2024-06-01 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: A gem providing "time travel" and "time freezing" capabilities, making
15
15
  it dead simple to test time-dependent code. It provides a unified method to mock
@@ -29,11 +29,6 @@ files:
29
29
  - lib/timecop/time_stack_item.rb
30
30
  - lib/timecop/timecop.rb
31
31
  - lib/timecop/version.rb
32
- - test/test_helper.rb
33
- - test/time_stack_item_test.rb
34
- - test/timecop_test.rb
35
- - test/timecop_without_date_but_with_time_test.rb
36
- - test/timecop_without_date_test.rb
37
32
  homepage: https://github.com/travisjeffery/timecop
38
33
  licenses:
39
34
  - MIT
@@ -56,13 +51,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
56
51
  requirements: []
57
52
  rubygems_version: 3.2.15
58
53
  signing_key:
59
- specification_version: 3
54
+ specification_version: 4
60
55
  summary: A gem providing "time travel" and "time freezing" capabilities, making it
61
56
  dead simple to test time-dependent code. It provides a unified method to mock Time.now,
62
57
  Date.today, and DateTime.now in a single call.
63
- test_files:
64
- - test/test_helper.rb
65
- - test/time_stack_item_test.rb
66
- - test/timecop_test.rb
67
- - test/timecop_without_date_test.rb
68
- - test/timecop_without_date_but_with_time_test.rb
58
+ test_files: []
data/test/test_helper.rb DELETED
@@ -1,59 +0,0 @@
1
- require 'bundler/setup'
2
- require 'minitest/autorun'
3
- require 'minitest/rg'
4
- require 'pry'
5
-
6
- $VERBOSE = true # enable ruby warnings
7
-
8
- require 'mocha/minitest'
9
-
10
- class Minitest::Test
11
- private
12
- # Tests to see that two times are within the given distance,
13
- # in seconds, from each other.
14
- def times_effectively_equal(time1, time2, seconds_interval = 1)
15
- (time1 - time2).abs <= seconds_interval
16
- end
17
-
18
- def assert_times_effectively_equal(time1, time2, seconds_interval = 1, msg = nil)
19
- assert times_effectively_equal(time1, time2, seconds_interval), "#{msg}: time1 = #{time1.to_s}, time2 = #{time2.to_s}"
20
- end
21
-
22
- def assert_times_effectively_not_equal(time1, time2, seconds_interval = 1, msg = nil)
23
- assert !times_effectively_equal(time1, time2, seconds_interval), "#{msg}: time1 = #{time1.to_s}, time2 = #{time2.to_s}"
24
- end
25
-
26
- # Gets the local offset (supplied by ENV['TZ'] or your computer's clock)
27
- # At the given timestamp, or Time.now if not time is given.
28
- def local_offset(time = Time.now)
29
- Time.at(time.to_i).to_datetime.offset
30
- end
31
-
32
- TIMEZONES = ["Pacific/Midway", "Europe/Paris", "UTC", "America/Chicago"]
33
-
34
- def each_timezone
35
- old_tz = ENV["TZ"]
36
-
37
- begin
38
- TIMEZONES.each do |timezone|
39
- ENV["TZ"] = timezone
40
- yield
41
- end
42
- ensure
43
- ENV["TZ"] = old_tz
44
- end
45
- end
46
-
47
- def a_time_stack_item
48
- Timecop::TimeStackItem.new(:freeze, 2008, 1, 1, 0, 0, 0)
49
- end
50
-
51
- def assert_date_times_equal(dt1, dt2)
52
- assert_in_delta dt1.to_time.to_f, dt2.to_time.to_f, 0.01, "Failed for timezone: #{ENV['TZ']}: #{dt1.to_s} not equal to #{dt2.to_s}"
53
- end
54
-
55
- def jruby?
56
- RUBY_PLATFORM == "java"
57
- end
58
-
59
- end
@@ -1,299 +0,0 @@
1
- require 'date'
2
- require_relative "test_helper"
3
- require 'timecop'
4
-
5
- require 'active_support/all'
6
-
7
- class TestTimeStackItem < Minitest::Test
8
- def teardown
9
- Timecop.return
10
- Time.zone = nil
11
- end
12
-
13
- def test_new_with_time
14
- t = Time.now
15
- y, m, d, h, min, s = t.year, t.month, t.day, t.hour, t.min, t.sec
16
- stack_item = Timecop::TimeStackItem.new(:freeze, t)
17
-
18
- assert_equal y, stack_item.year
19
- assert_equal m, stack_item.month
20
- assert_equal d, stack_item.day
21
- assert_equal h, stack_item.hour
22
- assert_equal min, stack_item.min
23
- assert_equal s, stack_item.sec
24
- end
25
-
26
- def test_new_with_time_and_arguments
27
- t = Time.new(2012, 7, 28, 20, 0)
28
- y, m, d, h, min, s = t.year, t.month, t.day, t.hour, t.min, t.sec
29
- stack_item = Timecop::TimeStackItem.new(:freeze, t)
30
-
31
- assert_equal y, stack_item.year
32
- assert_equal m, stack_item.month
33
- assert_equal d, stack_item.day
34
- assert_equal h, stack_item.hour
35
- assert_equal min, stack_item.min
36
- assert_equal s, stack_item.sec
37
- end
38
-
39
- def test_new_with_datetime_now
40
- t = DateTime.now
41
- y, m, d, h, min, s = t.year, t.month, t.day, t.hour, t.min, t.sec
42
- stack_item = Timecop::TimeStackItem.new(:freeze, t)
43
-
44
- assert_equal y, stack_item.year
45
- assert_equal m, stack_item.month
46
- assert_equal d, stack_item.day
47
- assert_equal h, stack_item.hour
48
- assert_equal min, stack_item.min
49
- assert_equal s, stack_item.sec
50
- end
51
-
52
- def test_new_with_datetime_in_different_timezone
53
- each_timezone do
54
- t = DateTime.parse("2009-10-11 00:38:00 +0200")
55
- stack_item = Timecop::TimeStackItem.new(:freeze, t)
56
-
57
- assert_date_times_equal(t, stack_item.datetime)
58
- end
59
- end
60
-
61
- def test_new_with_date
62
- date = Date.today
63
- y, m, d, h, min, s = date.year, date.month, date.day, 0, 0, 0
64
- stack_item = Timecop::TimeStackItem.new(:freeze, date)
65
-
66
- assert_equal y, stack_item.year
67
- assert_equal m, stack_item.month
68
- assert_equal d, stack_item.day
69
- assert_equal h, stack_item.hour
70
- assert_equal min, stack_item.min
71
- assert_equal s, stack_item.sec
72
- end
73
-
74
- # Due to the nature of this test (calling Time.now once in this test and
75
- # once in #new), this test may fail when two subsequent calls
76
- # to Time.now return a different second.
77
- def test_new_with_integer
78
- t = Time.now
79
- y, m, d, h, min, s = t.year, t.month, t.day, t.hour, t.min, t.sec
80
- stack_item = Timecop::TimeStackItem.new(:freeze, 0)
81
-
82
- assert_equal y, stack_item.year
83
- assert_equal m, stack_item.month
84
- assert_equal d, stack_item.day
85
- assert_equal h, stack_item.hour
86
- assert_equal min, stack_item.min
87
- assert_equal s, stack_item.sec
88
- end
89
-
90
- def test_new_with_float
91
- t = Time.now
92
- y, m, d, h, min, s = t.year, t.month, t.day, t.hour, t.min, t.sec
93
- stack_item = Timecop::TimeStackItem.new(:freeze, 0.0)
94
-
95
- assert_equal y, stack_item.year
96
- assert_equal m, stack_item.month
97
- assert_equal d, stack_item.day
98
- assert_equal h, stack_item.hour
99
- assert_equal min, stack_item.min
100
- assert_equal s, stack_item.sec
101
- end
102
-
103
- def test_new_with_individual_arguments
104
- y, m, d, h, min, s = 2008, 10, 10, 10, 10, 10
105
- stack_item = Timecop::TimeStackItem.new(:freeze, y, m, d, h, min, s)
106
-
107
- assert_equal y, stack_item.year
108
- assert_equal m, stack_item.month
109
- assert_equal d, stack_item.day
110
- assert_equal h, stack_item.hour
111
- assert_equal min, stack_item.min
112
- assert_equal s, stack_item.sec
113
- end
114
-
115
- def test_rational_to_utc_offset
116
- assert_equal -14400, a_time_stack_item.send(:rational_to_utc_offset, Rational(-1, 6))
117
- assert_equal -18000, a_time_stack_item.send(:rational_to_utc_offset, Rational(-5, 24))
118
- assert_equal 0, a_time_stack_item.send(:rational_to_utc_offset, Rational(0, 1))
119
- assert_equal 3600, a_time_stack_item.send(:rational_to_utc_offset, Rational(1, 24))
120
- end
121
-
122
- def test_utc_offset_to_rational
123
- assert_equal Rational(-1, 6), a_time_stack_item.send(:utc_offset_to_rational, -14400)
124
- assert_equal Rational(-5, 24), a_time_stack_item.send(:utc_offset_to_rational, -18000)
125
- assert_equal Rational(0, 1), a_time_stack_item.send(:utc_offset_to_rational, 0)
126
- assert_equal Rational(1, 24), a_time_stack_item.send(:utc_offset_to_rational, 3600)
127
- end
128
-
129
- def test_datetime_in_presence_of_activesupport_timezone
130
- skip('requires ActiveSupport') unless Time.respond_to? :zone
131
- backed_up_zone, backed_up_tzvar = Time.zone, ENV['TZ']
132
-
133
- Time.zone = ENV['TZ'] = 'America/Los_Angeles'
134
- t = DateTime.new(2001, 2, 28, 23, 59, 59.5)
135
- tsi = Timecop::TimeStackItem.new(:freeze, t)
136
-
137
- assert_date_times_equal t, tsi.datetime
138
- ensure
139
- Time.zone, ENV['TZ'] = backed_up_zone, backed_up_tzvar
140
- end
141
-
142
- # Ensure DateTimes handle changing DST properly
143
- def test_datetime_for_dst_to_non_dst
144
- Timecop.freeze(DateTime.parse("2009-12-1 00:38:00 -0500"))
145
- t = DateTime.parse("2009-10-11 00:00:00 -0400")
146
- tsi = Timecop::TimeStackItem.new(:freeze, t)
147
-
148
- assert_date_times_equal t, tsi.datetime
149
- end
150
-
151
- # Ensure DateTimes handle changing DST properly when changing from DateTime to Time
152
- def test_datetime_for_dst_to_time_for_non_dst
153
- Timecop.freeze(DateTime.parse("2009-12-1 00:38:00 -0500"))
154
- t = DateTime.parse("2009-10-11 00:00:00 -0400")
155
- tsi = Timecop::TimeStackItem.new(:freeze, t)
156
-
157
- assert_date_times_equal t.to_time, tsi.time
158
- end
159
-
160
- def test_datetime_for_non_dst_to_dst
161
- Timecop.freeze(DateTime.parse("2009-10-11 00:00:00 -0400"))
162
- t = DateTime.parse("2009-11-30 23:38:00 -0500")
163
- tsi = Timecop::TimeStackItem.new(:freeze, t)
164
- return if !tsi.time.dst?
165
-
166
- assert_date_times_equal t, tsi.datetime
167
- assert_equal Date.new(2009, 12, 1), tsi.date
168
- end
169
-
170
- def test_set_travel_offset_for_travel
171
- t_now = Time.now
172
- t = Time.local(2009, 10, 1, 0, 0, 30)
173
- expected_offset = t - t_now
174
- tsi = Timecop::TimeStackItem.new(:travel, t)
175
-
176
- assert_times_effectively_equal expected_offset, tsi.send(:travel_offset), 1, "Offset not calculated correctly"
177
- end
178
-
179
- def test_set_travel_offset_for_freeze
180
- Timecop.freeze(2009, 10, 1, 0, 0, 0)
181
- t = Time.local(2009, 10, 1, 0, 0, 30)
182
- tsi = Timecop::TimeStackItem.new(:freeze, t)
183
-
184
- assert_nil tsi.send(:travel_offset)
185
- end
186
-
187
- def test_timezones
188
- Time.zone = "Europe/Zurich"
189
- time = Time.zone.parse("2012-12-27T12:12:12+08:00")
190
- Timecop.freeze(time) do |frozen_time|
191
- assert_equal time, frozen_time
192
- end
193
- end
194
-
195
- def test_timezones_with_parsed_string
196
- Time.zone = "Europe/Zurich"
197
- time_string = "2012-12-27 12:12"
198
- expected_time = Time.zone.parse(time_string)
199
- Timecop.freeze(time_string) do |frozen_time|
200
- assert_equal expected_time, frozen_time
201
- end
202
- end
203
-
204
- def test_timezones_apply_dates
205
- Time.zone = "Central Time (US & Canada)"
206
- time = Time.zone.local(2013,1,3)
207
-
208
- Timecop.freeze(time) do
209
- assert_equal time.to_date, Time.zone.now.to_date
210
- end
211
- end
212
-
213
- def test_set_scaling_factor_for_scale
214
- t_now = Time.now
215
- t = Time.local(2009, 10, 1, 0, 0, 30)
216
- expected_offset = t - t_now
217
- tsi = Timecop::TimeStackItem.new(:scale, 4, t)
218
-
219
- assert_times_effectively_equal expected_offset, tsi.send(:travel_offset), 1, "Offset not calculated correctly"
220
- assert_equal tsi.send(:scaling_factor), 4, "Scaling factor not set"
221
- end
222
-
223
- def test_parse_only_string_with_active_support
224
- Time.expects(:parse).never
225
- Timecop.freeze(2011, 01, 02, hour=0, minute=0, second=0)
226
- end
227
-
228
- def test_parse_date
229
- Timecop.freeze(Date.new(2012, 6, 9))
230
- end
231
-
232
- def test_time_zone_returns_nil
233
- Time.zone = nil
234
- Timecop.freeze
235
- end
236
-
237
- def test_nsecs_are_set
238
- time = Time.now
239
- Timecop.freeze time
240
- assert_equal time, Time.now
241
- assert_equal time.nsec, Time.now.nsec if (Time.now.respond_to?(:nsec))
242
- end
243
-
244
- def test_time_with_different_timezone_keeps_nsec
245
- Time.zone = "Tokyo"
246
- t = Time.now
247
- Timecop.freeze(t) do
248
- assert_equal t, Time.now
249
- assert_equal t.nsec, Time.now.nsec if (Time.now.respond_to?(:nsec))
250
- end
251
- end
252
-
253
- def test_time_now_always_returns_local_time
254
- Time.zone = "Tokyo"
255
- t = Time.utc(2000, 1, 1)
256
- Timecop.freeze(t) do
257
- assert_equal t.getlocal.zone, Time.now.zone
258
- end
259
- end
260
-
261
- def test_time_zone_now_returns_time_in_that_zone
262
- Time.zone = "Hawaii"
263
- t = Time.utc(2000, 1, 1)
264
- Timecop.freeze(t) do
265
- assert_equal t, Time.zone.now
266
- assert_equal 'HST', Time.zone.now.zone
267
- end
268
- end
269
-
270
- def test_freezing_a_time_leaves_timezone_intact
271
- Time.zone = "Tokyo"
272
- t = Time.now
273
- t_dup = t.dup
274
- Timecop.freeze(t) {}
275
- assert_equal t_dup.zone, t.zone
276
- end
277
-
278
- def test_freezing_a_time_with_zone_returns_proper_zones
279
- Time.zone = "Hawaii"
280
- t = ActiveSupport::TimeWithZone.new(Time.utc(2000, 1, 1), ActiveSupport::TimeZone['Tokyo'])
281
- Timecop.freeze(t) do
282
- local_now = Time.now
283
- assert_equal t, local_now
284
- assert_equal t.getlocal.zone, local_now.zone
285
-
286
- zoned_now = Time.zone.now
287
- assert_equal t, zoned_now
288
- assert_equal 'HST', zoned_now.zone
289
- end
290
- end
291
-
292
- def test_datetime_timezones
293
- dt = DateTime.new(2011,1,3,15,25,0,"-6")
294
- Timecop.freeze(dt) do
295
- now = DateTime.now
296
- assert_equal dt, now, "#{dt.to_f}, #{now.to_f}"
297
- end
298
- end
299
- end