timecop 0.6.1 → 0.9.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +1 -1
- data/README.markdown +31 -16
- data/Rakefile +10 -4
- data/lib/timecop/time_extensions.rb +120 -47
- data/lib/timecop/time_stack_item.rb +109 -127
- data/lib/timecop/timecop.rb +104 -24
- data/lib/timecop/version.rb +1 -1
- data/test/test_helper.rb +26 -21
- data/test/time_stack_item_test.rb +98 -74
- data/test/timecop_test.rb +215 -31
- data/test/timecop_without_date_but_with_time_test.rb +4 -8
- data/test/timecop_without_date_test.rb +22 -23
- metadata +13 -17
- data/test/run_tests.sh +0 -6
data/lib/timecop/timecop.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'singleton'
|
2
|
-
require File.join(File.dirname(__FILE__), "time_extensions")
|
3
2
|
require File.join(File.dirname(__FILE__), "time_stack_item")
|
4
3
|
|
5
4
|
# Timecop
|
@@ -14,7 +13,7 @@ class Timecop
|
|
14
13
|
include Singleton
|
15
14
|
|
16
15
|
class << self
|
17
|
-
|
16
|
+
private :instance
|
18
17
|
|
19
18
|
# Allows you to run a block of code and "fake" a time throughout the execution of that block.
|
20
19
|
# This is particularly useful for writing test methods where the passage of time is critical to the business
|
@@ -33,6 +32,7 @@ class Timecop
|
|
33
32
|
# 3. Timecop.freeze(date_inst)
|
34
33
|
# 4. Timecop.freeze(offset_in_seconds)
|
35
34
|
# 5. Timecop.freeze(year, month, day, hour=0, minute=0, second=0)
|
35
|
+
# 6. Timecop.freeze() # Defaults to Time.now
|
36
36
|
#
|
37
37
|
# When a block is also passed, Time.now, DateTime.now and Date.today are all reset to their
|
38
38
|
# previous values after the block has finished executing. This allows us to nest multiple
|
@@ -76,11 +76,11 @@ class Timecop
|
|
76
76
|
end
|
77
77
|
|
78
78
|
def baseline
|
79
|
-
instance.
|
79
|
+
instance.baseline
|
80
80
|
end
|
81
81
|
|
82
82
|
def baseline=(baseline)
|
83
|
-
instance.
|
83
|
+
instance.baseline = baseline
|
84
84
|
end
|
85
85
|
|
86
86
|
# Reverts back to system's Time.now, Date.today and DateTime.now (if it exists) permamently when
|
@@ -88,73 +88,153 @@ class Timecop
|
|
88
88
|
# the given block.
|
89
89
|
def return(&block)
|
90
90
|
if block_given?
|
91
|
-
instance.
|
91
|
+
instance.return(&block)
|
92
92
|
else
|
93
|
-
instance.
|
93
|
+
instance.unmock!
|
94
94
|
nil
|
95
95
|
end
|
96
96
|
end
|
97
|
+
alias :unfreeze :return
|
97
98
|
|
98
99
|
def return_to_baseline
|
99
|
-
instance.
|
100
|
+
instance.return_to_baseline
|
100
101
|
Time.now
|
101
102
|
end
|
102
103
|
|
103
104
|
def top_stack_item #:nodoc:
|
104
|
-
instance.
|
105
|
+
instance.stack.last
|
106
|
+
end
|
107
|
+
|
108
|
+
def safe_mode=(safe)
|
109
|
+
@safe_mode = safe
|
110
|
+
end
|
111
|
+
|
112
|
+
def safe_mode?
|
113
|
+
@safe_mode ||= false
|
114
|
+
end
|
115
|
+
|
116
|
+
def thread_safe=(t)
|
117
|
+
instance.thread_safe = t
|
118
|
+
end
|
119
|
+
|
120
|
+
def thread_safe
|
121
|
+
instance.thread_safe
|
122
|
+
end
|
123
|
+
|
124
|
+
# Returns whether or not Timecop is currently frozen/travelled
|
125
|
+
def frozen?
|
126
|
+
!instance.stack.empty?
|
105
127
|
end
|
106
128
|
|
107
129
|
private
|
108
130
|
def send_travel(mock_type, *args, &block)
|
109
|
-
val = instance.
|
131
|
+
val = instance.travel(mock_type, *args, &block)
|
110
132
|
block_given? ? val : Time.now
|
111
133
|
end
|
112
134
|
end
|
113
135
|
|
114
|
-
|
136
|
+
def baseline=(b)
|
137
|
+
set_baseline(b)
|
138
|
+
stack << TimeStackItem.new(:travel, b)
|
139
|
+
end
|
140
|
+
|
141
|
+
def baseline
|
142
|
+
if @thread_safe
|
143
|
+
Thread.current[:timecop_baseline]
|
144
|
+
else
|
145
|
+
@baseline
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def set_baseline(b)
|
150
|
+
if @thread_safe
|
151
|
+
Thread.current[:timecop_baseline] = b
|
152
|
+
else
|
153
|
+
@baseline = b
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def stack
|
158
|
+
if @thread_safe
|
159
|
+
Thread.current[:timecop_stack] ||= []
|
160
|
+
Thread.current[:timecop_stack]
|
161
|
+
else
|
162
|
+
@stack
|
163
|
+
end
|
164
|
+
end
|
115
165
|
|
116
|
-
def
|
117
|
-
@
|
118
|
-
|
166
|
+
def set_stack(s)
|
167
|
+
if @thread_safe
|
168
|
+
Thread.current[:timecop_stack] = s
|
169
|
+
else
|
170
|
+
@stack = s
|
171
|
+
end
|
119
172
|
end
|
120
173
|
|
121
174
|
def initialize #:nodoc:
|
122
|
-
@
|
175
|
+
@stack = []
|
176
|
+
@safe = nil
|
177
|
+
@thread_safe = false
|
178
|
+
end
|
179
|
+
|
180
|
+
def thread_safe=(t)
|
181
|
+
initialize
|
182
|
+
@thread_safe = t
|
183
|
+
end
|
184
|
+
|
185
|
+
def thread_safe
|
186
|
+
@thread_safe
|
123
187
|
end
|
124
188
|
|
125
189
|
def travel(mock_type, *args, &block) #:nodoc:
|
190
|
+
raise SafeModeException if Timecop.safe_mode? && !block_given? && !@safe
|
191
|
+
|
126
192
|
stack_item = TimeStackItem.new(mock_type, *args)
|
127
193
|
|
128
|
-
|
194
|
+
stack_backup = stack.dup
|
195
|
+
stack << stack_item
|
129
196
|
|
130
197
|
if block_given?
|
198
|
+
safe_backup = @safe
|
199
|
+
@safe = true
|
131
200
|
begin
|
132
201
|
yield stack_item.time
|
133
202
|
ensure
|
134
|
-
|
203
|
+
stack.replace stack_backup
|
204
|
+
@safe = safe_backup
|
135
205
|
end
|
136
206
|
end
|
137
207
|
end
|
138
208
|
|
139
209
|
def return(&block)
|
140
|
-
current_stack =
|
141
|
-
current_baseline =
|
210
|
+
current_stack = stack
|
211
|
+
current_baseline = baseline
|
142
212
|
unmock!
|
143
213
|
yield
|
144
|
-
|
145
|
-
|
214
|
+
ensure
|
215
|
+
set_stack current_stack
|
216
|
+
set_baseline current_baseline
|
146
217
|
end
|
147
218
|
|
148
219
|
def unmock! #:nodoc:
|
149
|
-
|
150
|
-
|
220
|
+
set_baseline nil
|
221
|
+
set_stack []
|
151
222
|
end
|
152
223
|
|
153
224
|
def return_to_baseline
|
154
|
-
if
|
155
|
-
|
225
|
+
if baseline
|
226
|
+
set_stack [stack.shift]
|
156
227
|
else
|
157
228
|
unmock!
|
158
229
|
end
|
159
230
|
end
|
231
|
+
|
232
|
+
class SafeModeException < StandardError
|
233
|
+
def initialize
|
234
|
+
super "Safe mode is enabled, only calls passing a block are allowed."
|
235
|
+
end
|
236
|
+
end
|
160
237
|
end
|
238
|
+
|
239
|
+
# This must be done after TimeCop is available
|
240
|
+
require File.join(File.dirname(__FILE__), "time_extensions")
|
data/lib/timecop/version.rb
CHANGED
data/test/test_helper.rb
CHANGED
@@ -1,38 +1,39 @@
|
|
1
|
-
require 'rubygems'
|
2
1
|
require 'bundler/setup'
|
3
|
-
require '
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
end
|
2
|
+
require 'minitest/autorun'
|
3
|
+
require 'minitest/rg'
|
4
|
+
require 'pry'
|
5
|
+
|
6
|
+
$VERBOSE = true # enable ruby warnings
|
9
7
|
|
10
|
-
|
8
|
+
require 'mocha/minitest'
|
11
9
|
|
10
|
+
class Minitest::Test
|
12
11
|
private
|
13
12
|
# Tests to see that two times are within the given distance,
|
14
13
|
# in seconds, from each other.
|
15
14
|
def times_effectively_equal(time1, time2, seconds_interval = 1)
|
16
15
|
(time1 - time2).abs <= seconds_interval
|
17
16
|
end
|
18
|
-
|
17
|
+
|
19
18
|
def assert_times_effectively_equal(time1, time2, seconds_interval = 1, msg = nil)
|
20
19
|
assert times_effectively_equal(time1, time2, seconds_interval), "#{msg}: time1 = #{time1.to_s}, time2 = #{time2.to_s}"
|
21
20
|
end
|
22
|
-
|
21
|
+
|
23
22
|
def assert_times_effectively_not_equal(time1, time2, seconds_interval = 1, msg = nil)
|
24
23
|
assert !times_effectively_equal(time1, time2, seconds_interval), "#{msg}: time1 = #{time1.to_s}, time2 = #{time2.to_s}"
|
25
24
|
end
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
29
30
|
end
|
30
|
-
|
31
|
-
TIMEZONES = ["Europe/Paris", "UTC", "
|
32
|
-
|
31
|
+
|
32
|
+
TIMEZONES = ["Pacific/Midway", "Europe/Paris", "UTC", "America/Chicago"]
|
33
|
+
|
33
34
|
def each_timezone
|
34
35
|
old_tz = ENV["TZ"]
|
35
|
-
|
36
|
+
|
36
37
|
begin
|
37
38
|
TIMEZONES.each do |timezone|
|
38
39
|
ENV["TZ"] = timezone
|
@@ -42,13 +43,17 @@ class Test::Unit::TestCase
|
|
42
43
|
ENV["TZ"] = old_tz
|
43
44
|
end
|
44
45
|
end
|
45
|
-
|
46
|
+
|
46
47
|
def a_time_stack_item
|
47
48
|
Timecop::TimeStackItem.new(:freeze, 2008, 1, 1, 0, 0, 0)
|
48
49
|
end
|
49
|
-
|
50
|
+
|
50
51
|
def assert_date_times_equal(dt1, dt2)
|
51
|
-
|
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}"
|
52
53
|
end
|
53
|
-
|
54
|
+
|
55
|
+
def jruby?
|
56
|
+
RUBY_PLATFORM == "java"
|
57
|
+
end
|
58
|
+
|
54
59
|
end
|
@@ -1,11 +1,13 @@
|
|
1
1
|
require 'date'
|
2
|
-
|
3
|
-
require
|
2
|
+
require_relative "test_helper"
|
3
|
+
require 'timecop'
|
4
4
|
|
5
|
-
|
5
|
+
require 'active_support/all'
|
6
|
+
|
7
|
+
class TestTimeStackItem < Minitest::Test
|
6
8
|
def teardown
|
7
|
-
Timecop.active_support = nil
|
8
9
|
Timecop.return
|
10
|
+
Time.zone = nil
|
9
11
|
end
|
10
12
|
|
11
13
|
def test_new_with_time
|
@@ -85,6 +87,19 @@ class TestTimeStackItem < Test::Unit::TestCase
|
|
85
87
|
assert_equal s, stack_item.sec
|
86
88
|
end
|
87
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
|
+
|
88
103
|
def test_new_with_individual_arguments
|
89
104
|
y, m, d, h, min, s = 2008, 10, 10, 10, 10, 10
|
90
105
|
stack_item = Timecop::TimeStackItem.new(:freeze, y, m, d, h, min, s)
|
@@ -111,49 +126,35 @@ class TestTimeStackItem < Test::Unit::TestCase
|
|
111
126
|
assert_equal Rational(1, 24), a_time_stack_item.send(:utc_offset_to_rational, 3600)
|
112
127
|
end
|
113
128
|
|
114
|
-
def
|
115
|
-
|
116
|
-
|
117
|
-
tsi = Timecop::TimeStackItem.new(:freeze, t)
|
118
|
-
return if !(Time.now.dst? && tsi.time.dst?)
|
119
|
-
|
120
|
-
assert_equal 0, tsi.send(:dst_adjustment)
|
121
|
-
end
|
122
|
-
|
123
|
-
def test_compute_dst_adjustment_for_non_dst_to_non_dst
|
124
|
-
Timecop.freeze(DateTime.parse("2009-12-1 00:38:00 -0400"))
|
125
|
-
t = DateTime.parse("2009-12-11 00:00:00 -0400")
|
126
|
-
tsi = Timecop::TimeStackItem.new(:freeze, t)
|
127
|
-
return if Time.now.dst? || tsi.time.dst?
|
128
|
-
|
129
|
-
assert_equal 0, tsi.send(:dst_adjustment)
|
130
|
-
end
|
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']
|
131
132
|
|
132
|
-
|
133
|
-
|
134
|
-
t = DateTime.parse("2009-12-11 00:00:00 -0400")
|
133
|
+
Time.zone = ENV['TZ'] = 'America/Los_Angeles'
|
134
|
+
t = DateTime.new(2001, 2, 28, 23, 59, 59.5)
|
135
135
|
tsi = Timecop::TimeStackItem.new(:freeze, t)
|
136
|
-
return if !Time.now.dst? || tsi.time.dst?
|
137
136
|
|
138
|
-
|
137
|
+
assert_date_times_equal t, tsi.datetime
|
138
|
+
ensure
|
139
|
+
Time.zone, ENV['TZ'] = backed_up_zone, backed_up_tzvar
|
139
140
|
end
|
140
141
|
|
141
|
-
|
142
|
-
|
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"))
|
143
145
|
t = DateTime.parse("2009-10-11 00:00:00 -0400")
|
144
146
|
tsi = Timecop::TimeStackItem.new(:freeze, t)
|
145
|
-
return if Time.now.dst? || !tsi.time.dst?
|
146
147
|
|
147
|
-
|
148
|
+
assert_date_times_equal t, tsi.datetime
|
148
149
|
end
|
149
150
|
|
150
|
-
# Ensure DateTimes handle changing DST properly
|
151
|
-
def
|
151
|
+
# Ensure DateTimes handle changing DST properly when changing from DateTime to Time
|
152
|
+
def test_datetime_for_dst_to_time_for_non_dst
|
152
153
|
Timecop.freeze(DateTime.parse("2009-12-1 00:38:00 -0500"))
|
153
154
|
t = DateTime.parse("2009-10-11 00:00:00 -0400")
|
154
155
|
tsi = Timecop::TimeStackItem.new(:freeze, t)
|
155
156
|
|
156
|
-
assert_date_times_equal t, tsi.
|
157
|
+
assert_date_times_equal t.to_time, tsi.time
|
157
158
|
end
|
158
159
|
|
159
160
|
def test_datetime_for_non_dst_to_dst
|
@@ -180,11 +181,10 @@ class TestTimeStackItem < Test::Unit::TestCase
|
|
180
181
|
t = Time.local(2009, 10, 1, 0, 0, 30)
|
181
182
|
tsi = Timecop::TimeStackItem.new(:freeze, t)
|
182
183
|
|
183
|
-
|
184
|
+
assert_nil tsi.send(:travel_offset)
|
184
185
|
end
|
185
186
|
|
186
187
|
def test_timezones
|
187
|
-
require 'active_support/all'
|
188
188
|
Time.zone = "Europe/Zurich"
|
189
189
|
time = Time.zone.parse("2012-12-27T12:12:12+08:00")
|
190
190
|
Timecop.freeze(time) do |frozen_time|
|
@@ -192,13 +192,21 @@ class TestTimeStackItem < Test::Unit::TestCase
|
|
192
192
|
end
|
193
193
|
end
|
194
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
|
+
|
195
204
|
def test_timezones_apply_dates
|
196
|
-
|
197
|
-
Time.zone = "Marshall Is."
|
205
|
+
Time.zone = "Central Time (US & Canada)"
|
198
206
|
time = Time.zone.local(2013,1,3)
|
199
207
|
|
200
208
|
Timecop.freeze(time) do
|
201
|
-
assert_equal time.to_date,
|
209
|
+
assert_equal time.to_date, Time.zone.now.to_date
|
202
210
|
end
|
203
211
|
end
|
204
212
|
|
@@ -212,48 +220,18 @@ class TestTimeStackItem < Test::Unit::TestCase
|
|
212
220
|
assert_equal tsi.send(:scaling_factor), 4, "Scaling factor not set"
|
213
221
|
end
|
214
222
|
|
215
|
-
def test_parse_string_date_with_active_support
|
216
|
-
date = '2012-01-02'
|
217
|
-
Time.expects(:parse).with(date).returns(Time.local(2012, 01, 02))
|
218
|
-
Timecop.freeze(date)
|
219
|
-
end
|
220
|
-
|
221
223
|
def test_parse_only_string_with_active_support
|
222
224
|
Time.expects(:parse).never
|
223
225
|
Timecop.freeze(2011, 01, 02, hour=0, minute=0, second=0)
|
224
226
|
end
|
225
227
|
|
226
|
-
def test_parse_with_active_support_off
|
227
|
-
date = '2012-01-02'
|
228
|
-
Timecop.active_support = false
|
229
|
-
Time.expects(:parse).never
|
230
|
-
Timecop.freeze(date)
|
231
|
-
end
|
232
|
-
|
233
|
-
def test_uses_active_supports_in_time_zone
|
234
|
-
time = Time.now
|
235
|
-
Time.any_instance.expects(:in_time_zone).returns(time)
|
236
|
-
Timecop::TimeStackItem.new(:freeze, time)
|
237
|
-
end
|
238
|
-
|
239
|
-
def test_configured_off_active_support_in_time_zone_xxx
|
240
|
-
Timecop.active_support = false
|
241
|
-
Time.any_instance.expects(:in_time_zone).never
|
242
|
-
Timecop::TimeStackItem.new(:freeze, Time.now)
|
243
|
-
end
|
244
|
-
|
245
228
|
def test_parse_date
|
246
|
-
|
247
|
-
Timecop.freeze(Date.new(2012, 6, 9))
|
248
|
-
end
|
229
|
+
Timecop.freeze(Date.new(2012, 6, 9))
|
249
230
|
end
|
250
231
|
|
251
232
|
def test_time_zone_returns_nil
|
252
|
-
|
253
|
-
|
254
|
-
assert_nothing_raised do
|
255
|
-
Timecop.freeze
|
256
|
-
end
|
233
|
+
Time.zone = nil
|
234
|
+
Timecop.freeze
|
257
235
|
end
|
258
236
|
|
259
237
|
def test_nsecs_are_set
|
@@ -263,13 +241,59 @@ class TestTimeStackItem < Test::Unit::TestCase
|
|
263
241
|
assert_equal time.nsec, Time.now.nsec if (Time.now.respond_to?(:nsec))
|
264
242
|
end
|
265
243
|
|
266
|
-
def
|
267
|
-
|
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
|
268
269
|
|
270
|
+
def test_freezing_a_time_leaves_timezone_intact
|
269
271
|
Time.zone = "Tokyo"
|
270
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'])
|
271
281
|
Timecop.freeze(t) do
|
272
|
-
|
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}"
|
273
297
|
end
|
274
298
|
end
|
275
299
|
end
|