timecop 0.9.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 +5 -5
- data/LICENSE +1 -1
- data/README.markdown +3 -2
- data/lib/timecop/time_extensions.rb +31 -5
- data/lib/timecop/time_stack_item.rb +110 -110
- data/lib/timecop/timecop.rb +17 -14
- data/lib/timecop/version.rb +1 -1
- data/test/test_helper.rb +3 -2
- data/test/time_stack_item_test.rb +2 -2
- data/test/timecop_test.rb +50 -13
- metadata +6 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c86a01ea95f5019cb15a6a66c5668e68e7f1e293ca14b910a10cbe1cdd70d668
|
4
|
+
data.tar.gz: e5c6987d3a452fa9ead841021f93bf4ea6bac713c1f6cea38cfc1c1d49baf6ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4abbcd2d37b9fdf6dfb1ed1f63f945a882cd62a47ae2ae237da003ccac0bc660572be0800933ea484fb1632707bdc2de457b96f9aad8a62b1dfd96d766220692
|
7
|
+
data.tar.gz: a19cc9026478a29161a832454edebf76105d56d3841575af71e9dbaa305a40a68af285d17b7473369ae913e463cadd7b67ab2e099d13d3162b713d2c3cd87d05
|
data/LICENSE
CHANGED
data/README.markdown
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# timecop
|
2
2
|
|
3
|
-
[](https://rubygems.org/gems/timecop)
|
4
|
+
[](https://github.com/travisjeffery/timecop/actions?query=workflow%3ACI)
|
4
5
|
|
5
6
|
## DESCRIPTION
|
6
7
|
|
@@ -8,7 +9,7 @@ A gem providing "time travel" and "time freezing" capabilities, making it dead s
|
|
8
9
|
|
9
10
|
## INSTALL
|
10
11
|
|
11
|
-
`
|
12
|
+
`bundle add timecop`
|
12
13
|
|
13
14
|
## FEATURES
|
14
15
|
|
@@ -22,6 +22,8 @@ class Time #:nodoc:
|
|
22
22
|
args.size <= 0 ? now : new_without_mock_time(*args)
|
23
23
|
end
|
24
24
|
|
25
|
+
ruby2_keywords :new_with_mock_time if Module.private_method_defined?(:ruby2_keywords)
|
26
|
+
|
25
27
|
alias_method :new, :new_with_mock_time
|
26
28
|
end
|
27
29
|
end
|
@@ -43,12 +45,32 @@ class Date #:nodoc:
|
|
43
45
|
alias_method :strptime_without_mock_date, :strptime
|
44
46
|
|
45
47
|
def strptime_with_mock_date(str = '-4712-01-01', fmt = '%F', start = Date::ITALY)
|
46
|
-
|
47
|
-
|
48
|
-
|
48
|
+
#If date is not valid the following line raises
|
49
|
+
Date.strptime_without_mock_date(str, fmt, start)
|
50
|
+
|
51
|
+
d = Date._strptime(str, fmt)
|
52
|
+
now = Time.now.to_date
|
53
|
+
year = d[:year] || now.year
|
54
|
+
mon = d[:mon] || now.mon
|
55
|
+
if d.keys == [:year]
|
56
|
+
Date.new(year, 1, 1, start)
|
57
|
+
elsif d[:mday]
|
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
|
+
elsif d[:yday]
|
62
|
+
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)
|
68
|
+
end
|
69
|
+
elsif d[:seconds]
|
70
|
+
Time.at(d[:seconds]).to_date
|
71
|
+
else
|
72
|
+
Date.new(year, mon, 1, start)
|
49
73
|
end
|
50
|
-
|
51
|
-
Time.strptime(str, fmt).to_date
|
52
74
|
end
|
53
75
|
|
54
76
|
alias_method :strptime, :strptime_with_mock_date
|
@@ -63,6 +85,8 @@ class Date #:nodoc:
|
|
63
85
|
parsed_date
|
64
86
|
when date_hash[:mon] && date_hash[:mday]
|
65
87
|
Date.new(mocked_time_stack_item.year, date_hash[:mon], date_hash[:mday])
|
88
|
+
when date_hash[:mday]
|
89
|
+
Date.new(mocked_time_stack_item.year, mocked_time_stack_item.month, date_hash[:mday])
|
66
90
|
when date_hash[:wday]
|
67
91
|
closest_wday(date_hash[:wday])
|
68
92
|
else
|
@@ -111,6 +135,8 @@ class DateTime #:nodoc:
|
|
111
135
|
parsed_date
|
112
136
|
when date_hash[:mon] && date_hash[:mday]
|
113
137
|
DateTime.new(mocked_time_stack_item.year, date_hash[:mon], date_hash[:mday])
|
138
|
+
when date_hash[:mday]
|
139
|
+
DateTime.new(mocked_time_stack_item.year, mocked_time_stack_item.month, date_hash[:mday])
|
114
140
|
when date_hash[:wday]
|
115
141
|
Date.closest_wday(date_hash[:wday]).to_datetime
|
116
142
|
else
|
@@ -1,140 +1,140 @@
|
|
1
1
|
class Timecop
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
def year
|
18
|
-
time.year
|
19
|
-
end
|
2
|
+
# A data class for carrying around "time movement" objects. Makes it easy to keep track of the time
|
3
|
+
# movements on a simple stack.
|
4
|
+
class TimeStackItem #:nodoc:
|
5
|
+
attr_reader :mock_type
|
6
|
+
|
7
|
+
def initialize(mock_type, *args)
|
8
|
+
raise "Unknown mock_type #{mock_type}" unless [:freeze, :travel, :scale].include?(mock_type)
|
9
|
+
@travel_offset = @scaling_factor = nil
|
10
|
+
@scaling_factor = args.shift if mock_type == :scale
|
11
|
+
@mock_type = mock_type
|
12
|
+
@time = parse_time(*args)
|
13
|
+
@time_was = Time.now_without_mock_time
|
14
|
+
@travel_offset = compute_travel_offset
|
15
|
+
end
|
20
16
|
|
21
|
-
|
22
|
-
|
23
|
-
|
17
|
+
def year
|
18
|
+
time.year
|
19
|
+
end
|
24
20
|
|
25
|
-
|
26
|
-
|
27
|
-
|
21
|
+
def month
|
22
|
+
time.month
|
23
|
+
end
|
28
24
|
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
def day
|
26
|
+
time.day
|
27
|
+
end
|
32
28
|
|
33
|
-
|
34
|
-
|
35
|
-
|
29
|
+
def hour
|
30
|
+
time.hour
|
31
|
+
end
|
36
32
|
|
37
|
-
|
38
|
-
|
39
|
-
|
33
|
+
def min
|
34
|
+
time.min
|
35
|
+
end
|
40
36
|
|
41
|
-
|
42
|
-
|
43
|
-
|
37
|
+
def sec
|
38
|
+
time.sec
|
39
|
+
end
|
44
40
|
|
45
|
-
|
46
|
-
|
47
|
-
|
41
|
+
def utc_offset
|
42
|
+
time.utc_offset
|
43
|
+
end
|
48
44
|
|
49
|
-
|
50
|
-
|
51
|
-
|
45
|
+
def travel_offset
|
46
|
+
@travel_offset unless mock_type == :freeze
|
47
|
+
end
|
52
48
|
|
53
|
-
|
54
|
-
|
55
|
-
|
49
|
+
def travel_offset_days
|
50
|
+
(@travel_offset / 60 / 60 / 24).round
|
51
|
+
end
|
56
52
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
else
|
61
|
-
time = time_klass.at(@time)
|
62
|
-
end
|
53
|
+
def scaling_factor
|
54
|
+
@scaling_factor
|
55
|
+
end
|
63
56
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
time_klass.at(scaled_time)
|
70
|
-
end
|
57
|
+
def time(time_klass = Time) #:nodoc:
|
58
|
+
if @time.respond_to?(:in_time_zone)
|
59
|
+
time = time_klass.at(@time.dup.localtime)
|
60
|
+
else
|
61
|
+
time = time_klass.at(@time)
|
71
62
|
end
|
72
63
|
|
73
|
-
|
74
|
-
|
64
|
+
if travel_offset.nil?
|
65
|
+
time
|
66
|
+
elsif scaling_factor.nil?
|
67
|
+
time_klass.at(Time.now_without_mock_time + travel_offset)
|
68
|
+
else
|
69
|
+
time_klass.at(scaled_time)
|
75
70
|
end
|
71
|
+
end
|
76
72
|
|
77
|
-
|
78
|
-
|
79
|
-
|
73
|
+
def scaled_time
|
74
|
+
(@time + (Time.now_without_mock_time - @time_was) * scaling_factor).to_f
|
75
|
+
end
|
80
76
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
77
|
+
def date(date_klass = Date)
|
78
|
+
date_klass.jd(time.__send__(:to_date).jd)
|
79
|
+
end
|
80
|
+
|
81
|
+
def datetime(datetime_klass = DateTime)
|
82
|
+
if Float.method_defined?(:to_r)
|
83
|
+
fractions_of_a_second = time.to_f % 1
|
84
|
+
datetime_klass.new(year, month, day, hour, min, (fractions_of_a_second + sec), utc_offset_to_rational(utc_offset))
|
85
|
+
else
|
86
|
+
datetime_klass.new(year, month, day, hour, min, sec, utc_offset_to_rational(utc_offset))
|
88
87
|
end
|
88
|
+
end
|
89
89
|
|
90
|
-
|
90
|
+
private
|
91
91
|
|
92
|
-
|
93
|
-
|
94
|
-
|
92
|
+
def rational_to_utc_offset(rational)
|
93
|
+
((24.0 / rational.denominator) * rational.numerator) * (60 * 60)
|
94
|
+
end
|
95
95
|
|
96
|
-
|
97
|
-
|
98
|
-
|
96
|
+
def utc_offset_to_rational(utc_offset)
|
97
|
+
Rational(utc_offset, 24 * 60 * 60)
|
98
|
+
end
|
99
99
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
100
|
+
def parse_time(*args)
|
101
|
+
arg = args.shift
|
102
|
+
if arg.is_a?(Time)
|
103
|
+
arg
|
104
|
+
elsif Object.const_defined?(:DateTime) && arg.is_a?(DateTime)
|
105
|
+
time_klass.at(arg.to_time.to_f).getlocal
|
106
|
+
elsif Object.const_defined?(:Date) && arg.is_a?(Date)
|
107
|
+
time_klass.local(arg.year, arg.month, arg.day, 0, 0, 0)
|
108
|
+
elsif args.empty? && (arg.kind_of?(Integer) || arg.kind_of?(Float))
|
109
|
+
time_klass.now + arg
|
110
|
+
elsif arg.nil?
|
111
|
+
time_klass.now
|
112
|
+
else
|
113
|
+
if arg.is_a?(String) && Time.respond_to?(:parse)
|
114
|
+
time_klass.parse(arg)
|
112
115
|
else
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
minute = args.shift || 0
|
122
|
-
second = args.shift || 0
|
123
|
-
time_klass.local(year, month, day, hour, minute, second)
|
124
|
-
end
|
116
|
+
# we'll just assume it's a list of y/m/d/h/m/s
|
117
|
+
year = arg || 2000
|
118
|
+
month = args.shift || 1
|
119
|
+
day = args.shift || 1
|
120
|
+
hour = args.shift || 0
|
121
|
+
minute = args.shift || 0
|
122
|
+
second = args.shift || 0
|
123
|
+
time_klass.local(year, month, day, hour, minute, second)
|
125
124
|
end
|
126
125
|
end
|
126
|
+
end
|
127
127
|
|
128
|
-
|
129
|
-
|
130
|
-
|
128
|
+
def compute_travel_offset
|
129
|
+
time - Time.now_without_mock_time
|
130
|
+
end
|
131
131
|
|
132
|
-
|
133
|
-
|
134
|
-
|
132
|
+
def times_are_equal_within_epsilon t1, t2, epsilon_in_seconds
|
133
|
+
(t1 - t2).abs < epsilon_in_seconds
|
134
|
+
end
|
135
135
|
|
136
|
-
|
137
|
-
|
138
|
-
end
|
136
|
+
def time_klass
|
137
|
+
Time.respond_to?(:zone) && Time.zone ? Time.zone : Time
|
139
138
|
end
|
139
|
+
end
|
140
140
|
end
|
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,6 +13,8 @@ class Timecop
|
|
14
13
|
include Singleton
|
15
14
|
|
16
15
|
class << self
|
16
|
+
private :instance
|
17
|
+
|
17
18
|
# Allows you to run a block of code and "fake" a time throughout the execution of that block.
|
18
19
|
# This is particularly useful for writing test methods where the passage of time is critical to the business
|
19
20
|
# logic being tested. For example:
|
@@ -75,11 +76,11 @@ class Timecop
|
|
75
76
|
end
|
76
77
|
|
77
78
|
def baseline
|
78
|
-
instance.
|
79
|
+
instance.baseline
|
79
80
|
end
|
80
81
|
|
81
82
|
def baseline=(baseline)
|
82
|
-
instance.
|
83
|
+
instance.baseline = baseline
|
83
84
|
end
|
84
85
|
|
85
86
|
# Reverts back to system's Time.now, Date.today and DateTime.now (if it exists) permamently when
|
@@ -87,20 +88,21 @@ class Timecop
|
|
87
88
|
# the given block.
|
88
89
|
def return(&block)
|
89
90
|
if block_given?
|
90
|
-
instance.
|
91
|
+
instance.return(&block)
|
91
92
|
else
|
92
|
-
instance.
|
93
|
+
instance.unmock!
|
93
94
|
nil
|
94
95
|
end
|
95
96
|
end
|
97
|
+
alias :unfreeze :return
|
96
98
|
|
97
99
|
def return_to_baseline
|
98
|
-
instance.
|
100
|
+
instance.return_to_baseline
|
99
101
|
Time.now
|
100
102
|
end
|
101
103
|
|
102
104
|
def top_stack_item #:nodoc:
|
103
|
-
instance.
|
105
|
+
instance.stack.last
|
104
106
|
end
|
105
107
|
|
106
108
|
def safe_mode=(safe)
|
@@ -112,27 +114,25 @@ class Timecop
|
|
112
114
|
end
|
113
115
|
|
114
116
|
def thread_safe=(t)
|
115
|
-
instance.
|
117
|
+
instance.thread_safe = t
|
116
118
|
end
|
117
119
|
|
118
120
|
def thread_safe
|
119
|
-
instance.
|
121
|
+
instance.thread_safe
|
120
122
|
end
|
121
123
|
|
122
124
|
# Returns whether or not Timecop is currently frozen/travelled
|
123
125
|
def frozen?
|
124
|
-
!instance.
|
126
|
+
!instance.stack.empty?
|
125
127
|
end
|
126
128
|
|
127
129
|
private
|
128
130
|
def send_travel(mock_type, *args, &block)
|
129
|
-
val = instance.
|
131
|
+
val = instance.travel(mock_type, *args, &block)
|
130
132
|
block_given? ? val : Time.now
|
131
133
|
end
|
132
134
|
end
|
133
135
|
|
134
|
-
private
|
135
|
-
|
136
136
|
def baseline=(b)
|
137
137
|
set_baseline(b)
|
138
138
|
stack << TimeStackItem.new(:travel, b)
|
@@ -200,7 +200,7 @@ class Timecop
|
|
200
200
|
begin
|
201
201
|
yield stack_item.time
|
202
202
|
ensure
|
203
|
-
|
203
|
+
stack.replace stack_backup
|
204
204
|
@safe = safe_backup
|
205
205
|
end
|
206
206
|
end
|
@@ -235,3 +235,6 @@ class Timecop
|
|
235
235
|
end
|
236
236
|
end
|
237
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,10 +1,11 @@
|
|
1
1
|
require 'bundler/setup'
|
2
2
|
require 'minitest/autorun'
|
3
3
|
require 'minitest/rg'
|
4
|
+
require 'pry'
|
4
5
|
|
5
6
|
$VERBOSE = true # enable ruby warnings
|
6
7
|
|
7
|
-
require 'mocha/
|
8
|
+
require 'mocha/minitest'
|
8
9
|
|
9
10
|
class Minitest::Test
|
10
11
|
private
|
@@ -28,7 +29,7 @@ class Minitest::Test
|
|
28
29
|
Time.at(time.to_i).to_datetime.offset
|
29
30
|
end
|
30
31
|
|
31
|
-
TIMEZONES = ["Europe/Paris", "UTC", "America/Chicago"]
|
32
|
+
TIMEZONES = ["Pacific/Midway", "Europe/Paris", "UTC", "America/Chicago"]
|
32
33
|
|
33
34
|
def each_timezone
|
34
35
|
old_tz = ENV["TZ"]
|
@@ -181,7 +181,7 @@ class TestTimeStackItem < Minitest::Test
|
|
181
181
|
t = Time.local(2009, 10, 1, 0, 0, 30)
|
182
182
|
tsi = Timecop::TimeStackItem.new(:freeze, t)
|
183
183
|
|
184
|
-
|
184
|
+
assert_nil tsi.send(:travel_offset)
|
185
185
|
end
|
186
186
|
|
187
187
|
def test_timezones
|
@@ -206,7 +206,7 @@ class TestTimeStackItem < Minitest::Test
|
|
206
206
|
time = Time.zone.local(2013,1,3)
|
207
207
|
|
208
208
|
Timecop.freeze(time) do
|
209
|
-
assert_equal time.to_date, Time.now.to_date
|
209
|
+
assert_equal time.to_date, Time.zone.now.to_date
|
210
210
|
end
|
211
211
|
end
|
212
212
|
|
data/test/timecop_test.rb
CHANGED
@@ -37,6 +37,12 @@ class TestTimecop < Minitest::Test
|
|
37
37
|
assert_nil Time.send(:mock_time)
|
38
38
|
end
|
39
39
|
|
40
|
+
def test_freeze_then_unfreeze_unsets_mock_time
|
41
|
+
Timecop.freeze(1)
|
42
|
+
Timecop.unfreeze
|
43
|
+
assert_nil Time.send(:mock_time)
|
44
|
+
end
|
45
|
+
|
40
46
|
def test_travel_then_return_unsets_mock_time
|
41
47
|
Timecop.travel(1)
|
42
48
|
Timecop.return
|
@@ -283,6 +289,17 @@ class TestTimecop < Minitest::Test
|
|
283
289
|
t = Time.local(2008, 10, 10, 10, 10, 10)
|
284
290
|
assert_times_effectively_equal t, Timecop.scale(4, t)
|
285
291
|
end
|
292
|
+
|
293
|
+
def test_scaling_returns_now_if_nil_supplied
|
294
|
+
assert_times_effectively_equal Time.now, Timecop.scale(nil)
|
295
|
+
end
|
296
|
+
|
297
|
+
def test_scaling_raises_when_empty_string_supplied
|
298
|
+
err = assert_raises(TypeError) do
|
299
|
+
Timecop.scale("")
|
300
|
+
end
|
301
|
+
assert_match /String can't be coerced into Float/, err.message
|
302
|
+
end
|
286
303
|
|
287
304
|
def test_freeze_with_utc_time
|
288
305
|
each_timezone do
|
@@ -388,6 +405,10 @@ class TestTimecop < Minitest::Test
|
|
388
405
|
end
|
389
406
|
assert_times_effectively_equal(time_after_travel, Time.now)
|
390
407
|
end
|
408
|
+
|
409
|
+
def test_travel_returns_now_if_nil_supplied
|
410
|
+
assert_times_effectively_equal Time.now, Timecop.travel(nil)
|
411
|
+
end
|
391
412
|
|
392
413
|
def test_travel_time_with_block_returns_the_value_of_the_block
|
393
414
|
t_future = Time.local(2030, 10, 10, 10, 10, 10)
|
@@ -396,6 +417,13 @@ class TestTimecop < Minitest::Test
|
|
396
417
|
|
397
418
|
assert_equal expected, actual
|
398
419
|
end
|
420
|
+
|
421
|
+
def test_travel_raises_when_empty_string_supplied
|
422
|
+
err = assert_raises(ArgumentError) do
|
423
|
+
Timecop.travel("")
|
424
|
+
end
|
425
|
+
assert_match /no time information in \"\"/, err.message
|
426
|
+
end
|
399
427
|
|
400
428
|
def test_freeze_time_returns_now_if_no_block_given
|
401
429
|
t_future = Time.local(2030, 10, 10, 10, 10, 10)
|
@@ -422,6 +450,17 @@ class TestTimecop < Minitest::Test
|
|
422
450
|
end
|
423
451
|
end
|
424
452
|
end
|
453
|
+
|
454
|
+
def test_freeze_returns_now_if_nil_supplied
|
455
|
+
assert_times_effectively_equal Time.now, Timecop.freeze(nil)
|
456
|
+
end
|
457
|
+
|
458
|
+
def test_freeze_raises_when_empty_string_supplied
|
459
|
+
err = assert_raises(ArgumentError) do
|
460
|
+
Timecop.freeze("")
|
461
|
+
end
|
462
|
+
assert_match /no time information in \"\"/, err.message
|
463
|
+
end
|
425
464
|
|
426
465
|
def test_freeze_with_new_date
|
427
466
|
date = Date.new(2012, 6, 9)
|
@@ -527,18 +566,6 @@ class TestTimecop < Minitest::Test
|
|
527
566
|
end
|
528
567
|
end
|
529
568
|
|
530
|
-
def test_date_strptime_without_year
|
531
|
-
Timecop.freeze(Time.new(1984,2,28)) do
|
532
|
-
assert_equal Date.strptime('04-14', '%m-%d'), Date.new(1984, 4, 14)
|
533
|
-
end
|
534
|
-
end
|
535
|
-
|
536
|
-
def test_date_strptime_without_specifying_format
|
537
|
-
Timecop.freeze(Time.new(1984,2,28)) do
|
538
|
-
assert_equal Date.strptime('1999-04-14'), Date.new(1999, 4, 14)
|
539
|
-
end
|
540
|
-
end
|
541
|
-
|
542
569
|
def test_frozen_after_freeze
|
543
570
|
Timecop.freeze
|
544
571
|
assert Timecop.frozen?
|
@@ -556,7 +583,7 @@ class TestTimecop < Minitest::Test
|
|
556
583
|
assert !Timecop.frozen?
|
557
584
|
end
|
558
585
|
|
559
|
-
def
|
586
|
+
def test_thread_safe_timecop_in_parallel
|
560
587
|
Timecop.thread_safe = true
|
561
588
|
date = Time.local(2011, 01, 02)
|
562
589
|
thread = Thread.new do
|
@@ -573,6 +600,16 @@ class TestTimecop < Minitest::Test
|
|
573
600
|
Timecop.thread_safe = false
|
574
601
|
end
|
575
602
|
|
603
|
+
def test_thread_safe_timecop_returns_after_block
|
604
|
+
Timecop.thread_safe = true
|
605
|
+
date = Time.local(2017, 10, 8)
|
606
|
+
|
607
|
+
Timecop.freeze(date) { }
|
608
|
+
assert Time.now != date
|
609
|
+
ensure
|
610
|
+
Timecop.thread_safe = false
|
611
|
+
end
|
612
|
+
|
576
613
|
private
|
577
614
|
|
578
615
|
def with_safe_mode(enabled=true)
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: timecop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Travis Jeffery
|
8
8
|
- John Trupiano
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2022-11-29 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
|
@@ -38,7 +38,7 @@ homepage: https://github.com/travisjeffery/timecop
|
|
38
38
|
licenses:
|
39
39
|
- MIT
|
40
40
|
metadata: {}
|
41
|
-
post_install_message:
|
41
|
+
post_install_message:
|
42
42
|
rdoc_options:
|
43
43
|
- "--charset=UTF-8"
|
44
44
|
require_paths:
|
@@ -54,9 +54,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: '0'
|
56
56
|
requirements: []
|
57
|
-
|
58
|
-
|
59
|
-
signing_key:
|
57
|
+
rubygems_version: 3.2.15
|
58
|
+
signing_key:
|
60
59
|
specification_version: 3
|
61
60
|
summary: A gem providing "time travel" and "time freezing" capabilities, making it
|
62
61
|
dead simple to test time-dependent code. It provides a unified method to mock Time.now,
|
@@ -67,4 +66,3 @@ test_files:
|
|
67
66
|
- test/timecop_test.rb
|
68
67
|
- test/timecop_without_date_test.rb
|
69
68
|
- test/timecop_without_date_but_with_time_test.rb
|
70
|
-
has_rdoc:
|