timecop 0.9.8 → 0.9.9
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 +4 -4
- data/README.markdown +1 -1
- data/lib/timecop/time_extensions.rb +65 -0
- data/lib/timecop/time_stack_item.rb +31 -0
- data/lib/timecop/timecop.rb +16 -0
- data/lib/timecop/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5ffc3899071434ff0ae8eb0a9e4a6ea4c2d8794547113c272bdc24a384d2eb45
|
4
|
+
data.tar.gz: e9333e4c2cf362558c432d7b954a724ff588e66c4dcce8d3af4a327dd6dcb894
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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
|
|
@@ -143,8 +143,17 @@ class DateTime #:nodoc:
|
|
143
143
|
DateTime.new(mocked_time_stack_item.year, date_hash[:mon], date_hash[:mday])
|
144
144
|
when date_hash[:mday]
|
145
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
|
+
)
|
146
153
|
when date_hash[:wday]
|
147
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])
|
148
157
|
else
|
149
158
|
parsed_date + mocked_time_stack_item.travel_offset_days
|
150
159
|
end
|
@@ -158,3 +167,59 @@ class DateTime #:nodoc:
|
|
158
167
|
end
|
159
168
|
end
|
160
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)
|
data/lib/timecop/timecop.rb
CHANGED
@@ -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.
|
@@ -126,6 +132,16 @@ class Timecop
|
|
126
132
|
!instance.stack.empty? && instance.stack.last.mock_type == :freeze
|
127
133
|
end
|
128
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
|
143
|
+
end
|
144
|
+
|
129
145
|
private
|
130
146
|
def send_travel(mock_type, *args, &block)
|
131
147
|
val = instance.travel(mock_type, *args, &block)
|
data/lib/timecop/version.rb
CHANGED
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.
|
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:
|
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
|