timecop 0.6.1 → 0.6.3
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/README.markdown +21 -10
- data/Rakefile +2 -2
- data/lib/timecop/time_extensions.rb +30 -49
- data/lib/timecop/time_stack_item.rb +17 -35
- data/lib/timecop/timecop.rb +18 -3
- data/lib/timecop/version.rb +1 -1
- data/test/run_tests.sh +6 -2
- data/test/test_helper.rb +1 -1
- data/test/time_stack_item_test.rb +63 -65
- data/test/timecop_test.rb +66 -9
- metadata +7 -9
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 28306a2c78d6588f97b394b65bba1163a9a1cf4a
|
|
4
|
+
data.tar.gz: c2323a791bb954e70a70b9595cb56135e54ff64d
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 5e445072106712764a97139527912b59ec29cb0e4a97b4a1203dd8c5d72aebea0788935ca56fec863285cb2d764f3312ad604f1d311fa51fcd4ea07a9bd4c8d8
|
|
7
|
+
data.tar.gz: 6f690a4c4d944c7f3df343616bb4e78c707e0efaf8b9c102d71da2a72029bffb0d26dcd64dea856e59183c04cc98d5c0c5d5c7549892338dc823ba3d963968cc
|
data/README.markdown
CHANGED
|
@@ -11,7 +11,7 @@ A gem providing "time travel" and "time freezing" capabilities, making it dead s
|
|
|
11
11
|
|
|
12
12
|
## INSTALL
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
`gem install timecop`
|
|
15
15
|
|
|
16
16
|
## FEATURES
|
|
17
17
|
|
|
@@ -49,7 +49,7 @@ describe "some set of tests to mock" do
|
|
|
49
49
|
before do
|
|
50
50
|
Timecop.freeze(Time.local(1990))
|
|
51
51
|
end
|
|
52
|
-
|
|
52
|
+
|
|
53
53
|
after do
|
|
54
54
|
Timecop.return
|
|
55
55
|
end
|
|
@@ -62,7 +62,7 @@ Set the time for the test environment of a rails app -- this is particularly
|
|
|
62
62
|
helpful if your whole application is time-sensitive. It allows you to build
|
|
63
63
|
your test data at a single point in time, and to move in/out of that time as
|
|
64
64
|
appropriate (within your tests)
|
|
65
|
-
|
|
65
|
+
|
|
66
66
|
in config/environments/test.rb
|
|
67
67
|
|
|
68
68
|
```ruby
|
|
@@ -111,19 +111,30 @@ Time.now
|
|
|
111
111
|
# => 2012-09-21 06:22:59 -0500
|
|
112
112
|
```
|
|
113
113
|
|
|
114
|
-
|
|
114
|
+
<<<<<<< HEAD
|
|
115
|
+
### Timecop.safe_mode
|
|
116
|
+
|
|
117
|
+
Safe mode forces you to use Timecop with the block syntax since it always puts time back the way it was. If you are running in safe mode and use Timecop without the block syntax `Timecop::SafeModeException` will be raised to tell the user they are not being safe.
|
|
115
118
|
|
|
116
|
-
|
|
119
|
+
``` ruby
|
|
120
|
+
# turn on safe mode
|
|
121
|
+
Timecop.safe_mode = true
|
|
122
|
+
|
|
123
|
+
# check if you are in safe mode
|
|
124
|
+
Timecop.safe_mode?
|
|
125
|
+
# => true
|
|
126
|
+
|
|
127
|
+
# using method without block
|
|
128
|
+
Timecop.freeze
|
|
129
|
+
# => Timecop::SafeModeException: Safe mode is enabled, only calls passing a block are allowed.
|
|
130
|
+
```
|
|
117
131
|
|
|
118
|
-
|
|
119
|
-
* {0.3.0 release}[http://blog.smartlogicsolutions.com/2009/09/20/timecop-0-3-0-released/]
|
|
120
|
-
* {0.2.0 release}[http://blog.smartlogicsolutions.com/2008/12/24/timecop-2-released-freeze-and-rebase-time-ruby/]
|
|
121
|
-
* {0.1.0 release}[http://blog.smartlogicsolutions.com/2008/11/19/timecop-freeze-time-in-ruby-for-better-testing/]
|
|
132
|
+
See [#42](https://github.com/travisjeffery/timecop/pull/42) for more information, thanks to Ken Mayer, David Holcomb, and Pivotal Labs.
|
|
122
133
|
|
|
123
134
|
## Contribute
|
|
124
135
|
|
|
125
136
|
timecop is maintained by [travisjeffery](http://github.com/travisjeffery), and
|
|
126
|
-
was created by [jtrupiano](https://github.com/jtrupiano).
|
|
137
|
+
was created by [jtrupiano](https://github.com/jtrupiano).
|
|
127
138
|
|
|
128
139
|
Here's the most direct way to get your work merged into the project.
|
|
129
140
|
|
data/Rakefile
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require 'date'
|
|
1
2
|
|
|
2
3
|
class Time #:nodoc:
|
|
3
4
|
class << self
|
|
@@ -5,77 +6,57 @@ class Time #:nodoc:
|
|
|
5
6
|
mocked_time_stack_item = Timecop.top_stack_item
|
|
6
7
|
mocked_time_stack_item.nil? ? nil : mocked_time_stack_item.time(self)
|
|
7
8
|
end
|
|
8
|
-
|
|
9
|
+
|
|
9
10
|
alias_method :now_without_mock_time, :now
|
|
10
11
|
|
|
11
12
|
def now_with_mock_time
|
|
12
13
|
mock_time || now_without_mock_time
|
|
13
14
|
end
|
|
14
|
-
|
|
15
|
+
|
|
15
16
|
alias_method :now, :now_with_mock_time
|
|
16
17
|
|
|
17
18
|
alias_method :new_without_mock_time, :new
|
|
18
19
|
|
|
19
20
|
def new_with_mock_time(*args)
|
|
20
|
-
|
|
21
|
-
raise ArgumentError.new if args.size <= 0
|
|
22
|
-
new_without_mock_time(*args)
|
|
23
|
-
rescue ArgumentError
|
|
24
|
-
now
|
|
25
|
-
end
|
|
21
|
+
args.size <= 0 ? now : new_without_mock_time(*args)
|
|
26
22
|
end
|
|
27
23
|
|
|
28
24
|
alias_method :new, :new_with_mock_time
|
|
29
25
|
end
|
|
30
|
-
end
|
|
26
|
+
end
|
|
31
27
|
|
|
32
|
-
|
|
33
|
-
class
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
mocked_time_stack_item.nil? ? nil : mocked_time_stack_item.date(self)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
alias_method :today_without_mock_date, :today
|
|
41
|
-
|
|
42
|
-
def today_with_mock_date
|
|
43
|
-
mock_date || today_without_mock_date
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
alias_method :today, :today_with_mock_date
|
|
28
|
+
class Date #:nodoc:
|
|
29
|
+
class << self
|
|
30
|
+
def mock_date
|
|
31
|
+
mocked_time_stack_item = Timecop.top_stack_item
|
|
32
|
+
mocked_time_stack_item.nil? ? nil : mocked_time_stack_item.date(self)
|
|
47
33
|
end
|
|
34
|
+
|
|
35
|
+
alias_method :today_without_mock_date, :today
|
|
36
|
+
|
|
37
|
+
def today_with_mock_date
|
|
38
|
+
mock_date || today_without_mock_date
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
alias_method :today, :today_with_mock_date
|
|
48
42
|
end
|
|
49
43
|
end
|
|
50
44
|
|
|
51
|
-
|
|
52
|
-
class
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def now_without_mock_time
|
|
60
|
-
Time.now_without_mock_time.to_datetime
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def now_with_mock_time
|
|
64
|
-
mock_time || now_without_mock_time
|
|
65
|
-
end
|
|
45
|
+
class DateTime #:nodoc:
|
|
46
|
+
class << self
|
|
47
|
+
def mock_time
|
|
48
|
+
mocked_time_stack_item = Timecop.top_stack_item
|
|
49
|
+
mocked_time_stack_item.nil? ? nil : mocked_time_stack_item.datetime(self)
|
|
50
|
+
end
|
|
66
51
|
|
|
67
|
-
|
|
52
|
+
def now_without_mock_time
|
|
53
|
+
Time.now_without_mock_time.to_datetime
|
|
68
54
|
end
|
|
69
|
-
end
|
|
70
55
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
class DateTime
|
|
74
|
-
class << self
|
|
75
|
-
def now_without_mock_time
|
|
76
|
-
Time.now_without_mock_time.send(:to_datetime)
|
|
77
|
-
end
|
|
78
|
-
end
|
|
56
|
+
def now_with_mock_time
|
|
57
|
+
mock_time || now_without_mock_time
|
|
79
58
|
end
|
|
59
|
+
|
|
60
|
+
alias_method :now, :now_with_mock_time
|
|
80
61
|
end
|
|
81
62
|
end
|
|
@@ -11,7 +11,6 @@ class Timecop
|
|
|
11
11
|
@time = parse_time(*args)
|
|
12
12
|
@time_was = Time.now_without_mock_time
|
|
13
13
|
@travel_offset = compute_travel_offset
|
|
14
|
-
@dst_adjustment = compute_dst_adjustment(@time)
|
|
15
14
|
end
|
|
16
15
|
|
|
17
16
|
def year
|
|
@@ -50,21 +49,19 @@ class Timecop
|
|
|
50
49
|
@scaling_factor
|
|
51
50
|
end
|
|
52
51
|
|
|
53
|
-
def time(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
time =
|
|
58
|
-
rescue
|
|
59
|
-
time = klass.at(@time.to_f)
|
|
52
|
+
def time(time_klass = Time) #:nodoc:
|
|
53
|
+
if @time.respond_to?(:in_time_zone)
|
|
54
|
+
time = time_klass.at(@time.utc.to_r)
|
|
55
|
+
else
|
|
56
|
+
time = time_klass.at(@time)
|
|
60
57
|
end
|
|
61
58
|
|
|
62
59
|
if travel_offset.nil?
|
|
63
60
|
time
|
|
64
61
|
elsif scaling_factor.nil?
|
|
65
|
-
|
|
62
|
+
time_klass.at((Time.now_without_mock_time + travel_offset).to_f)
|
|
66
63
|
else
|
|
67
|
-
|
|
64
|
+
time_klass.at(scaled_time)
|
|
68
65
|
end
|
|
69
66
|
end
|
|
70
67
|
|
|
@@ -77,21 +74,18 @@ class Timecop
|
|
|
77
74
|
end
|
|
78
75
|
|
|
79
76
|
def datetime(datetime_klass = DateTime)
|
|
80
|
-
our_offset = utc_offset + dst_adjustment
|
|
81
|
-
|
|
82
77
|
if Float.method_defined?(:to_r)
|
|
83
|
-
|
|
84
|
-
|
|
78
|
+
if !sec.zero?
|
|
79
|
+
fractions_of_a_second = time.to_f % 1
|
|
80
|
+
datetime_klass.new(year, month, day, hour, min, (fractions_of_a_second + sec), utc_offset_to_rational(utc_offset))
|
|
81
|
+
else
|
|
82
|
+
datetime_klass.new(year, month, day, hour, min, sec, utc_offset_to_rational(utc_offset))
|
|
83
|
+
end
|
|
85
84
|
else
|
|
86
|
-
|
|
87
|
-
datetime_klass.new(year, month, day, hour, min, sec, utc_offset_to_rational(our_offset))
|
|
85
|
+
datetime_klass.new(year, month, day, hour, min, sec, utc_offset_to_rational(utc_offset))
|
|
88
86
|
end
|
|
89
87
|
end
|
|
90
88
|
|
|
91
|
-
def dst_adjustment
|
|
92
|
-
@dst_adjustment
|
|
93
|
-
end
|
|
94
|
-
|
|
95
89
|
private
|
|
96
90
|
|
|
97
91
|
def rational_to_utc_offset(rational)
|
|
@@ -105,15 +99,9 @@ class Timecop
|
|
|
105
99
|
def parse_time(*args)
|
|
106
100
|
arg = args.shift
|
|
107
101
|
if arg.is_a?(Time)
|
|
108
|
-
|
|
109
|
-
arg.in_time_zone
|
|
110
|
-
else
|
|
111
|
-
arg.getlocal
|
|
112
|
-
end
|
|
102
|
+
arg
|
|
113
103
|
elsif Object.const_defined?(:DateTime) && arg.is_a?(DateTime)
|
|
114
|
-
|
|
115
|
-
expected_time += expected_time.utc_offset - rational_to_utc_offset(arg.offset)
|
|
116
|
-
expected_time + compute_dst_adjustment(expected_time)
|
|
104
|
+
time_klass.at(arg.to_time.to_f).getlocal
|
|
117
105
|
elsif Object.const_defined?(:Date) && arg.is_a?(Date)
|
|
118
106
|
time_klass.local(arg.year, arg.month, arg.day, 0, 0, 0)
|
|
119
107
|
elsif args.empty? && arg.kind_of?(Integer)
|
|
@@ -121,7 +109,7 @@ class Timecop
|
|
|
121
109
|
elsif arg.nil?
|
|
122
110
|
Time.now
|
|
123
111
|
else
|
|
124
|
-
if arg.is_a?(String) &&
|
|
112
|
+
if arg.is_a?(String) && Time.respond_to?(:parse)
|
|
125
113
|
Time.parse(arg)
|
|
126
114
|
else
|
|
127
115
|
# we'll just assume it's a list of y/m/d/h/m/s
|
|
@@ -136,12 +124,6 @@ class Timecop
|
|
|
136
124
|
end
|
|
137
125
|
end
|
|
138
126
|
|
|
139
|
-
def compute_dst_adjustment(time)
|
|
140
|
-
return 0 if !(time.dst? ^ Time.now.dst?)
|
|
141
|
-
return -1 * 60 * 60 if time.dst?
|
|
142
|
-
return 60 * 60
|
|
143
|
-
end
|
|
144
|
-
|
|
145
127
|
def compute_travel_offset
|
|
146
128
|
return nil if mock_type == :freeze
|
|
147
129
|
time - Time.now_without_mock_time
|
data/lib/timecop/timecop.rb
CHANGED
|
@@ -14,8 +14,6 @@ class Timecop
|
|
|
14
14
|
include Singleton
|
|
15
15
|
|
|
16
16
|
class << self
|
|
17
|
-
attr_accessor :active_support
|
|
18
|
-
|
|
19
17
|
# Allows you to run a block of code and "fake" a time throughout the execution of that block.
|
|
20
18
|
# This is particularly useful for writing test methods where the passage of time is critical to the business
|
|
21
19
|
# logic being tested. For example:
|
|
@@ -104,6 +102,14 @@ class Timecop
|
|
|
104
102
|
instance.instance_variable_get(:@_stack).last
|
|
105
103
|
end
|
|
106
104
|
|
|
105
|
+
def safe_mode=(safe)
|
|
106
|
+
@safe_mode = safe
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def safe_mode?
|
|
110
|
+
false || @safe_mode
|
|
111
|
+
end
|
|
112
|
+
|
|
107
113
|
private
|
|
108
114
|
def send_travel(mock_type, *args, &block)
|
|
109
115
|
val = instance.send(:travel, mock_type, *args, &block)
|
|
@@ -123,15 +129,18 @@ class Timecop
|
|
|
123
129
|
end
|
|
124
130
|
|
|
125
131
|
def travel(mock_type, *args, &block) #:nodoc:
|
|
132
|
+
raise SafeModeException if Timecop.safe_mode? && !block_given?
|
|
133
|
+
|
|
126
134
|
stack_item = TimeStackItem.new(mock_type, *args)
|
|
127
135
|
|
|
136
|
+
stack_backup = @_stack.dup
|
|
128
137
|
@_stack << stack_item
|
|
129
138
|
|
|
130
139
|
if block_given?
|
|
131
140
|
begin
|
|
132
141
|
yield stack_item.time
|
|
133
142
|
ensure
|
|
134
|
-
@_stack.
|
|
143
|
+
@_stack.replace stack_backup
|
|
135
144
|
end
|
|
136
145
|
end
|
|
137
146
|
end
|
|
@@ -157,4 +166,10 @@ class Timecop
|
|
|
157
166
|
unmock!
|
|
158
167
|
end
|
|
159
168
|
end
|
|
169
|
+
|
|
170
|
+
class SafeModeException < StandardError
|
|
171
|
+
def initialize
|
|
172
|
+
super "Safe mode is enabled, only calls passing a block are allowed."
|
|
173
|
+
end
|
|
174
|
+
end
|
|
160
175
|
end
|
data/lib/timecop/version.rb
CHANGED
data/test/run_tests.sh
CHANGED
data/test/test_helper.rb
CHANGED
|
@@ -48,7 +48,7 @@ class Test::Unit::TestCase
|
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
def assert_date_times_equal(dt1, dt2)
|
|
51
|
-
|
|
51
|
+
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
52
|
end
|
|
53
53
|
|
|
54
54
|
end
|
|
@@ -2,10 +2,12 @@ require 'date'
|
|
|
2
2
|
require File.join(File.dirname(__FILE__), "test_helper")
|
|
3
3
|
require File.join(File.dirname(__FILE__), '..', 'lib', 'timecop')
|
|
4
4
|
|
|
5
|
+
require 'active_support/all'
|
|
6
|
+
|
|
5
7
|
class TestTimeStackItem < Test::Unit::TestCase
|
|
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
|
|
@@ -111,49 +113,35 @@ class TestTimeStackItem < Test::Unit::TestCase
|
|
|
111
113
|
assert_equal Rational(1, 24), a_time_stack_item.send(:utc_offset_to_rational, 3600)
|
|
112
114
|
end
|
|
113
115
|
|
|
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
|
|
116
|
+
def test_datetime_in_presence_of_activesupport_timezone
|
|
117
|
+
skip('requires ActiveSupport') unless Time.respond_to? :zone
|
|
118
|
+
backed_up_zone, backed_up_tzvar = Time.zone, ENV['TZ']
|
|
131
119
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
t = DateTime.parse("2009-12-11 00:00:00 -0400")
|
|
120
|
+
Time.zone = ENV['TZ'] = 'America/Los_Angeles'
|
|
121
|
+
t = DateTime.new(2001, 2, 28, 23, 59, 59.5)
|
|
135
122
|
tsi = Timecop::TimeStackItem.new(:freeze, t)
|
|
136
|
-
return if !Time.now.dst? || tsi.time.dst?
|
|
137
123
|
|
|
138
|
-
|
|
124
|
+
assert_date_times_equal t, tsi.datetime
|
|
125
|
+
ensure
|
|
126
|
+
Time.zone, ENV['TZ'] = backed_up_zone, backed_up_tzvar
|
|
139
127
|
end
|
|
140
128
|
|
|
141
|
-
|
|
142
|
-
|
|
129
|
+
# Ensure DateTimes handle changing DST properly
|
|
130
|
+
def test_datetime_for_dst_to_non_dst
|
|
131
|
+
Timecop.freeze(DateTime.parse("2009-12-1 00:38:00 -0500"))
|
|
143
132
|
t = DateTime.parse("2009-10-11 00:00:00 -0400")
|
|
144
133
|
tsi = Timecop::TimeStackItem.new(:freeze, t)
|
|
145
|
-
return if Time.now.dst? || !tsi.time.dst?
|
|
146
134
|
|
|
147
|
-
|
|
135
|
+
assert_date_times_equal t, tsi.datetime
|
|
148
136
|
end
|
|
149
137
|
|
|
150
|
-
# Ensure DateTimes handle changing DST properly
|
|
151
|
-
def
|
|
138
|
+
# Ensure DateTimes handle changing DST properly when changing from DateTime to Time
|
|
139
|
+
def test_datetime_for_dst_to_time_for_non_dst
|
|
152
140
|
Timecop.freeze(DateTime.parse("2009-12-1 00:38:00 -0500"))
|
|
153
141
|
t = DateTime.parse("2009-10-11 00:00:00 -0400")
|
|
154
142
|
tsi = Timecop::TimeStackItem.new(:freeze, t)
|
|
155
143
|
|
|
156
|
-
assert_date_times_equal t, tsi.
|
|
144
|
+
assert_date_times_equal t.to_time, tsi.time
|
|
157
145
|
end
|
|
158
146
|
|
|
159
147
|
def test_datetime_for_non_dst_to_dst
|
|
@@ -184,7 +172,6 @@ class TestTimeStackItem < Test::Unit::TestCase
|
|
|
184
172
|
end
|
|
185
173
|
|
|
186
174
|
def test_timezones
|
|
187
|
-
require 'active_support/all'
|
|
188
175
|
Time.zone = "Europe/Zurich"
|
|
189
176
|
time = Time.zone.parse("2012-12-27T12:12:12+08:00")
|
|
190
177
|
Timecop.freeze(time) do |frozen_time|
|
|
@@ -193,12 +180,11 @@ class TestTimeStackItem < Test::Unit::TestCase
|
|
|
193
180
|
end
|
|
194
181
|
|
|
195
182
|
def test_timezones_apply_dates
|
|
196
|
-
|
|
197
|
-
Time.zone = "Marshall Is."
|
|
183
|
+
Time.zone = "Central Time (US & Canada)"
|
|
198
184
|
time = Time.zone.local(2013,1,3)
|
|
199
185
|
|
|
200
186
|
Timecop.freeze(time) do
|
|
201
|
-
assert_equal time.to_date,
|
|
187
|
+
assert_equal time.to_date, Time.now.to_date
|
|
202
188
|
end
|
|
203
189
|
end
|
|
204
190
|
|
|
@@ -212,36 +198,11 @@ class TestTimeStackItem < Test::Unit::TestCase
|
|
|
212
198
|
assert_equal tsi.send(:scaling_factor), 4, "Scaling factor not set"
|
|
213
199
|
end
|
|
214
200
|
|
|
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
201
|
def test_parse_only_string_with_active_support
|
|
222
202
|
Time.expects(:parse).never
|
|
223
203
|
Timecop.freeze(2011, 01, 02, hour=0, minute=0, second=0)
|
|
224
204
|
end
|
|
225
205
|
|
|
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
206
|
def test_parse_date
|
|
246
207
|
assert_nothing_raised do
|
|
247
208
|
Timecop.freeze(Date.new(2012, 6, 9))
|
|
@@ -249,8 +210,7 @@ class TestTimeStackItem < Test::Unit::TestCase
|
|
|
249
210
|
end
|
|
250
211
|
|
|
251
212
|
def test_time_zone_returns_nil
|
|
252
|
-
|
|
253
|
-
c.send(:define_method, :zone) { nil }
|
|
213
|
+
Time.zone = nil
|
|
254
214
|
assert_nothing_raised do
|
|
255
215
|
Timecop.freeze
|
|
256
216
|
end
|
|
@@ -263,13 +223,51 @@ class TestTimeStackItem < Test::Unit::TestCase
|
|
|
263
223
|
assert_equal time.nsec, Time.now.nsec if (Time.now.respond_to?(:nsec))
|
|
264
224
|
end
|
|
265
225
|
|
|
266
|
-
def
|
|
267
|
-
require 'active_support/all'
|
|
268
|
-
|
|
226
|
+
def test_time_with_different_timezone_keeps_nsec
|
|
269
227
|
Time.zone = "Tokyo"
|
|
270
228
|
t = Time.now
|
|
271
229
|
Timecop.freeze(t) do
|
|
272
|
-
|
|
230
|
+
assert_equal t, Time.now
|
|
231
|
+
assert_equal t.nsec, Time.now.nsec if (Time.now.respond_to?(:nsec))
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
def test_time_now_always_returns_local_time
|
|
236
|
+
Time.zone = "Tokyo"
|
|
237
|
+
t = Time.utc(2000, 1, 1)
|
|
238
|
+
Timecop.freeze(t) do
|
|
239
|
+
assert_equal t.getlocal.zone, Time.now.zone
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def test_time_zone_now_returns_time_in_that_zone
|
|
244
|
+
Time.zone = "Hawaii"
|
|
245
|
+
t = Time.utc(2000, 1, 1)
|
|
246
|
+
Timecop.freeze(t) do
|
|
247
|
+
assert_equal t, Time.zone.now
|
|
248
|
+
assert_equal 'HST', Time.zone.now.zone
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def test_freezing_a_time_with_zone_returns_proper_zones
|
|
253
|
+
Time.zone = "Hawaii"
|
|
254
|
+
t = ActiveSupport::TimeWithZone.new(Time.utc(2000, 1, 1), ActiveSupport::TimeZone['Tokyo'])
|
|
255
|
+
Timecop.freeze(t) do
|
|
256
|
+
local_now = Time.now
|
|
257
|
+
assert_equal t, local_now
|
|
258
|
+
assert_equal t.getlocal.zone, local_now.zone
|
|
259
|
+
|
|
260
|
+
zoned_now = Time.zone.now
|
|
261
|
+
assert_equal t, zoned_now
|
|
262
|
+
assert_equal 'HST', zoned_now.zone
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def test_datetime_timezones
|
|
267
|
+
dt = DateTime.new(2011,1,3,15,25,0,"-6")
|
|
268
|
+
Timecop.travel(dt) do
|
|
269
|
+
now = DateTime.now
|
|
270
|
+
assert_equal dt, now, "#{dt.to_f}, #{now.to_f}"
|
|
273
271
|
end
|
|
274
272
|
end
|
|
275
273
|
end
|
data/test/timecop_test.rb
CHANGED
|
@@ -8,16 +8,22 @@ class TestTimecop < Test::Unit::TestCase
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def test_freeze_changes_and_resets_time
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
Timecop.freeze(
|
|
17
|
-
|
|
11
|
+
outer_freeze_time = Time.local(2001, 01, 01)
|
|
12
|
+
inner_freeze_block = Time.local(2002, 02, 02)
|
|
13
|
+
inner_freeze_one = Time.local(2003, 03, 03)
|
|
14
|
+
inner_freeze_two = Time.local(2004, 04, 04)
|
|
15
|
+
|
|
16
|
+
Timecop.freeze(outer_freeze_time) do
|
|
17
|
+
assert_times_effectively_equal outer_freeze_time, Time.now
|
|
18
|
+
Timecop.freeze(inner_freeze_block) do
|
|
19
|
+
assert_times_effectively_equal inner_freeze_block, Time.now
|
|
20
|
+
Timecop.freeze(inner_freeze_one)
|
|
21
|
+
assert_times_effectively_equal inner_freeze_one, Time.now
|
|
22
|
+
Timecop.freeze(inner_freeze_two)
|
|
23
|
+
assert_times_effectively_equal inner_freeze_two, Time.now
|
|
24
|
+
end
|
|
25
|
+
assert_times_effectively_equal outer_freeze_time, Time.now
|
|
18
26
|
end
|
|
19
|
-
|
|
20
|
-
assert_not_equal t, Time.now
|
|
21
27
|
end
|
|
22
28
|
|
|
23
29
|
def test_freeze_yields_mocked_time
|
|
@@ -435,4 +441,55 @@ class TestTimecop < Test::Unit::TestCase
|
|
|
435
441
|
Timecop.send_travel(:travel, Time.now - 100)
|
|
436
442
|
end
|
|
437
443
|
end
|
|
444
|
+
|
|
445
|
+
def test_datetime_to_time_for_dst_to_non_dst
|
|
446
|
+
# Start at a time subject to DST
|
|
447
|
+
Timecop.travel(2009, 4, 1, 0, 0, 0, -4*60*60) do
|
|
448
|
+
|
|
449
|
+
# Then freeze, via DateTime, at a time not subject to DST
|
|
450
|
+
t = DateTime.new(2009,01,01,0,0,0, "-0500")
|
|
451
|
+
Timecop.freeze(t) do
|
|
452
|
+
|
|
453
|
+
# Check the current time via DateTime.now--should be what we asked for
|
|
454
|
+
assert_date_times_equal t, DateTime.now
|
|
455
|
+
|
|
456
|
+
# Then check the current time via Time.now (not DateTime.now)
|
|
457
|
+
assert_times_effectively_equal Time.new(2009, 1, 1, 0, 0, 0, -5*60*60), Time.now
|
|
458
|
+
end
|
|
459
|
+
end
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
def test_raises_when_safe_mode_and_no_block
|
|
463
|
+
with_safe_mode do
|
|
464
|
+
assert_raise Timecop::SafeModeException do
|
|
465
|
+
Timecop.freeze
|
|
466
|
+
end
|
|
467
|
+
end
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
def test_no_raise_when_safe_mode_and_block_used
|
|
471
|
+
with_safe_mode do
|
|
472
|
+
assert_nothing_raised do
|
|
473
|
+
Timecop.freeze {}
|
|
474
|
+
end
|
|
475
|
+
end
|
|
476
|
+
end
|
|
477
|
+
|
|
478
|
+
def test_no_raise_when_not_safe_mode_and_no_block
|
|
479
|
+
with_safe_mode(false) do
|
|
480
|
+
assert_nothing_raised do
|
|
481
|
+
Timecop.freeze
|
|
482
|
+
end
|
|
483
|
+
end
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
private
|
|
487
|
+
|
|
488
|
+
def with_safe_mode(enabled=true)
|
|
489
|
+
mode = Timecop.safe_mode?
|
|
490
|
+
Timecop.safe_mode = enabled
|
|
491
|
+
yield
|
|
492
|
+
ensure
|
|
493
|
+
Timecop.safe_mode = mode
|
|
494
|
+
end
|
|
438
495
|
end
|
metadata
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: timecop
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.6.
|
|
5
|
-
prerelease:
|
|
4
|
+
version: 0.6.3
|
|
6
5
|
platform: ruby
|
|
7
6
|
authors:
|
|
8
7
|
- Travis Jeffery
|
|
@@ -10,7 +9,7 @@ authors:
|
|
|
10
9
|
autorequire:
|
|
11
10
|
bindir: bin
|
|
12
11
|
cert_chain: []
|
|
13
|
-
date: 2013-
|
|
12
|
+
date: 2013-08-04 00:00:00.000000000 Z
|
|
14
13
|
dependencies: []
|
|
15
14
|
description: A gem providing "time travel" and "time freezing" capabilities, making
|
|
16
15
|
it dead simple to test time-dependent code. It provides a unified method to mock
|
|
@@ -39,26 +38,25 @@ files:
|
|
|
39
38
|
homepage: https://github.com/travisjeffery/timecop
|
|
40
39
|
licenses:
|
|
41
40
|
- MIT
|
|
41
|
+
metadata: {}
|
|
42
42
|
post_install_message:
|
|
43
43
|
rdoc_options:
|
|
44
44
|
- --charset=UTF-8
|
|
45
45
|
require_paths:
|
|
46
46
|
- lib
|
|
47
47
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
48
|
-
none: false
|
|
49
48
|
requirements:
|
|
50
|
-
- -
|
|
49
|
+
- - '>='
|
|
51
50
|
- !ruby/object:Gem::Version
|
|
52
|
-
version:
|
|
51
|
+
version: 1.9.2
|
|
53
52
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
54
|
-
none: false
|
|
55
53
|
requirements:
|
|
56
|
-
- -
|
|
54
|
+
- - '>='
|
|
57
55
|
- !ruby/object:Gem::Version
|
|
58
56
|
version: '0'
|
|
59
57
|
requirements: []
|
|
60
58
|
rubyforge_project: timecop
|
|
61
|
-
rubygems_version:
|
|
59
|
+
rubygems_version: 2.0.3
|
|
62
60
|
signing_key:
|
|
63
61
|
specification_version: 3
|
|
64
62
|
summary: A gem providing "time travel" and "time freezing" capabilities, making it
|