timecop 0.5.1 → 0.6.0
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.
- data/README.markdown +41 -3
- data/lib/timecop/time_extensions.rb +14 -18
- data/lib/timecop/time_stack_item.rb +106 -81
- data/lib/timecop/timecop.rb +73 -46
- data/lib/timecop/version.rb +2 -2
- data/lib/timecop.rb +2 -2
- data/test/test_helper.rb +5 -1
- data/test/time_stack_item_test.rb +79 -22
- data/test/timecop_test.rb +45 -13
- data/test/timecop_without_date_test.rb +1 -1
- metadata +7 -7
- data/History.rdoc +0 -132
data/README.markdown
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# timecop
|
|
2
2
|
|
|
3
|
-
-
|
|
3
|
+
[](http://travis-ci.org/travisjeffery/timecop)
|
|
4
|
+
|
|
5
|
+
- Source[http://github.com/travisjeffery/timecop]
|
|
4
6
|
- Documentation[http://johntrupiano.rubyforge.org/timecop]
|
|
5
7
|
|
|
6
8
|
## DESCRIPTION
|
|
@@ -15,6 +17,7 @@ A gem providing "time travel" and "time freezing" capabilities, making it dead s
|
|
|
15
17
|
|
|
16
18
|
- Freeze time to a specific point.
|
|
17
19
|
- Travel back to a specific point in time, but allow time to continue moving forward from there.
|
|
20
|
+
- Scale time by a given scaling factor that will cause time to move at an accelerated pace.
|
|
18
21
|
- No dependencies, can be used with _any_ ruby project
|
|
19
22
|
- Timecop api allows arguments to be passed into #freeze and #travel as one of the following:
|
|
20
23
|
- Time instance
|
|
@@ -39,6 +42,22 @@ Timecop.freeze(Date.today + 30) do
|
|
|
39
42
|
end
|
|
40
43
|
```
|
|
41
44
|
|
|
45
|
+
You can mock the time for a set of tests easily via setup/teardown methods
|
|
46
|
+
|
|
47
|
+
```ruby
|
|
48
|
+
describe "some set of tests to mock" do
|
|
49
|
+
before do
|
|
50
|
+
Timecop.freeze(Time.local(1990))
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
after do
|
|
54
|
+
Timecop.return
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it "should do blah blah blah" {}
|
|
58
|
+
end
|
|
59
|
+
```
|
|
60
|
+
|
|
42
61
|
Set the time for the test environment of a rails app -- this is particularly
|
|
43
62
|
helpful if your whole application is time-sensitive. It allows you to build
|
|
44
63
|
your test data at a single point in time, and to move in/out of that time as
|
|
@@ -75,6 +94,25 @@ sleep(10)
|
|
|
75
94
|
new_time == Time.now # ==> false
|
|
76
95
|
```
|
|
77
96
|
|
|
97
|
+
### Timecop.scale
|
|
98
|
+
|
|
99
|
+
Let's say you want to test a "live" integration wherein entire days could pass by
|
|
100
|
+
in minutes while you're able to simulate "real" activity. For example, one such use case
|
|
101
|
+
is being able to test reports and invoices that run in 30 day cycles in very little time, while also
|
|
102
|
+
being able to simulate activity via subsequent calls to your application.
|
|
103
|
+
|
|
104
|
+
```ruby
|
|
105
|
+
# seconds will now seem like hours
|
|
106
|
+
Timecop.scale(3600)
|
|
107
|
+
Time.now
|
|
108
|
+
# => 2012-09-20 21:23:25 -0500
|
|
109
|
+
# seconds later, hours have past it's gone from 9pm at night to 6am in the morning
|
|
110
|
+
Time.now
|
|
111
|
+
# => 2012-09-21 06:22:59 -0500
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
See #42 for more information, thanks to Ken Mayer, David Holcomb, and Pivotal Labs.
|
|
115
|
+
|
|
78
116
|
## REFERENCES
|
|
79
117
|
|
|
80
118
|
* {0.3.4 release}[http://blog.smartlogicsolutions.com/2009/12/07/timecop-0-3-4-released/]
|
|
@@ -84,8 +122,8 @@ new_time == Time.now # ==> false
|
|
|
84
122
|
|
|
85
123
|
## Contribute
|
|
86
124
|
|
|
87
|
-
timecop is maintained by [travisjeffery](http://github.com/travisjeffery),
|
|
88
|
-
|
|
125
|
+
timecop is maintained by [travisjeffery](http://github.com/travisjeffery), and
|
|
126
|
+
was created by [jtrupiano](https://github.com/jtrupiano).
|
|
89
127
|
|
|
90
128
|
Here's the most direct way to get your work merged into the project.
|
|
91
129
|
|
|
@@ -1,29 +1,25 @@
|
|
|
1
1
|
|
|
2
2
|
class Time #:nodoc:
|
|
3
3
|
class << self
|
|
4
|
-
# Time we are behaving as
|
|
5
4
|
def mock_time
|
|
6
5
|
mocked_time_stack_item = Timecop.top_stack_item
|
|
7
6
|
mocked_time_stack_item.nil? ? nil : mocked_time_stack_item.time(self)
|
|
8
7
|
end
|
|
9
8
|
|
|
10
|
-
# Alias the original now
|
|
11
9
|
alias_method :now_without_mock_time, :now
|
|
12
10
|
|
|
13
|
-
# Define now_with_mock_time
|
|
14
11
|
def now_with_mock_time
|
|
15
12
|
mock_time || now_without_mock_time
|
|
16
13
|
end
|
|
17
14
|
|
|
18
|
-
# Alias now to now_with_mock_time
|
|
19
15
|
alias_method :now, :now_with_mock_time
|
|
20
16
|
|
|
21
17
|
alias_method :new_without_mock_time, :new
|
|
22
18
|
|
|
23
|
-
def new_with_mock_time
|
|
19
|
+
def new_with_mock_time(*args)
|
|
24
20
|
begin
|
|
25
21
|
raise ArgumentError.new if args.size <= 0
|
|
26
|
-
new_without_mock_time
|
|
22
|
+
new_without_mock_time(*args)
|
|
27
23
|
rescue ArgumentError
|
|
28
24
|
now
|
|
29
25
|
end
|
|
@@ -36,21 +32,17 @@ end
|
|
|
36
32
|
if Object.const_defined?(:Date) && Date.respond_to?(:today)
|
|
37
33
|
class Date #:nodoc:
|
|
38
34
|
class << self
|
|
39
|
-
# Date we are behaving as
|
|
40
35
|
def mock_date
|
|
41
36
|
mocked_time_stack_item = Timecop.top_stack_item
|
|
42
37
|
mocked_time_stack_item.nil? ? nil : mocked_time_stack_item.date(self)
|
|
43
38
|
end
|
|
44
39
|
|
|
45
|
-
# Alias the original today
|
|
46
40
|
alias_method :today_without_mock_date, :today
|
|
47
41
|
|
|
48
|
-
# Define today_with_mock_date
|
|
49
42
|
def today_with_mock_date
|
|
50
43
|
mock_date || today_without_mock_date
|
|
51
44
|
end
|
|
52
45
|
|
|
53
|
-
# Alias today to today_with_mock_date
|
|
54
46
|
alias_method :today, :today_with_mock_date
|
|
55
47
|
end
|
|
56
48
|
end
|
|
@@ -59,27 +51,31 @@ end
|
|
|
59
51
|
if Object.const_defined?(:DateTime) && DateTime.respond_to?(:now)
|
|
60
52
|
class DateTime #:nodoc:
|
|
61
53
|
class << self
|
|
62
|
-
# Time we are behaving as
|
|
63
54
|
def mock_time
|
|
64
55
|
mocked_time_stack_item = Timecop.top_stack_item
|
|
65
56
|
mocked_time_stack_item.nil? ? nil : mocked_time_stack_item.datetime(self)
|
|
66
57
|
end
|
|
67
58
|
|
|
68
|
-
# Fake alias :now_without_mock_time :now
|
|
69
|
-
# It appears that the DateTime library itself references Time.now
|
|
70
|
-
# for it's interpretation of now which caused
|
|
71
|
-
# DateTime.now_without_mock_time to incorrectly return the frozen time.
|
|
72
59
|
def now_without_mock_time
|
|
73
|
-
Time.now_without_mock_time.
|
|
60
|
+
Time.now_without_mock_time.to_datetime
|
|
74
61
|
end
|
|
75
62
|
|
|
76
|
-
# Define now_with_mock_time
|
|
77
63
|
def now_with_mock_time
|
|
78
64
|
mock_time || now_without_mock_time
|
|
79
65
|
end
|
|
80
66
|
|
|
81
|
-
# Alias now to now_with_mock_time
|
|
82
67
|
alias_method :now, :now_with_mock_time
|
|
83
68
|
end
|
|
84
69
|
end
|
|
70
|
+
|
|
71
|
+
# for ruby1.8
|
|
72
|
+
unless Time::public_instance_methods.include? :to_datetime
|
|
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
|
|
79
|
+
end
|
|
80
|
+
end
|
|
85
81
|
end
|
|
@@ -1,92 +1,110 @@
|
|
|
1
|
-
|
|
2
1
|
class Timecop
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def year
|
|
17
|
-
time.year
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def month
|
|
21
|
-
time.month
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def day
|
|
25
|
-
time.day
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def hour
|
|
29
|
-
time.hour
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def min
|
|
33
|
-
time.min
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def sec
|
|
37
|
-
time.sec
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def utc_offset
|
|
41
|
-
time.utc_offset
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def travel_offset
|
|
45
|
-
@travel_offset
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def time(time_klass=Time) #:nodoc:
|
|
49
|
-
if travel_offset.nil?
|
|
50
|
-
time_klass.at( @time.to_f )
|
|
51
|
-
else
|
|
52
|
-
time_klass.at( ( Time.now_without_mock_time + travel_offset ).to_f )
|
|
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
|
+
@scaling_factor = args.shift if mock_type == :scale
|
|
10
|
+
@mock_type = mock_type
|
|
11
|
+
@time = parse_time(*args)
|
|
12
|
+
@time_was = Time.now_without_mock_time
|
|
13
|
+
@travel_offset = compute_travel_offset
|
|
14
|
+
@dst_adjustment = compute_dst_adjustment(@time)
|
|
53
15
|
end
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
16
|
+
|
|
17
|
+
def year
|
|
18
|
+
time.year
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def month
|
|
22
|
+
time.month
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def day
|
|
26
|
+
time.day
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def hour
|
|
30
|
+
time.hour
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def min
|
|
34
|
+
time.min
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def sec
|
|
38
|
+
time.sec
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def utc_offset
|
|
42
|
+
time.utc_offset
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def travel_offset
|
|
46
|
+
@travel_offset
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def scaling_factor
|
|
50
|
+
@scaling_factor
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def time(klass = time_klass) #:nodoc:
|
|
54
|
+
begin
|
|
55
|
+
actual_time = klass.at(@time)
|
|
56
|
+
calculated_time = klass.at(@time.to_f)
|
|
57
|
+
time = times_are_equal_within_epsilon(actual_time, calculated_time, 1) ? actual_time : calculated_time
|
|
58
|
+
rescue
|
|
59
|
+
time = klass.at(@time.to_f)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
if travel_offset.nil?
|
|
63
|
+
time
|
|
64
|
+
elsif scaling_factor.nil?
|
|
65
|
+
klass.at(Time.now_without_mock_time + travel_offset)
|
|
66
|
+
else
|
|
67
|
+
klass.at(scaled_time)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def scaled_time
|
|
72
|
+
(@time + (Time.now_without_mock_time - @time_was) * scaling_factor).to_f
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def date(date_klass = Date)
|
|
76
|
+
date_klass.jd(time.__send__(:to_date).jd)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def datetime(datetime_klass = DateTime)
|
|
68
80
|
our_offset = utc_offset + dst_adjustment
|
|
69
|
-
|
|
81
|
+
|
|
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, sec + fractions_of_a_second, utc_offset_to_rational(our_offset))
|
|
85
|
+
else
|
|
86
|
+
our_offset = utc_offset + dst_adjustment
|
|
87
|
+
datetime_klass.new(year, month, day, hour, min, sec, utc_offset_to_rational(our_offset))
|
|
88
|
+
end
|
|
70
89
|
end
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
90
|
+
|
|
91
|
+
def dst_adjustment
|
|
92
|
+
@dst_adjustment
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
private
|
|
96
|
+
|
|
78
97
|
def rational_to_utc_offset(rational)
|
|
79
98
|
((24.0 / rational.denominator) * rational.numerator) * (60 * 60)
|
|
80
99
|
end
|
|
81
|
-
|
|
100
|
+
|
|
82
101
|
def utc_offset_to_rational(utc_offset)
|
|
83
102
|
Rational(utc_offset, 24 * 60 * 60)
|
|
84
103
|
end
|
|
85
|
-
|
|
104
|
+
|
|
86
105
|
def parse_time(*args)
|
|
87
|
-
time_klass = Time.respond_to?(:zone) && Time.zone ? Time.zone : Time
|
|
88
106
|
arg = args.shift
|
|
89
|
-
if arg.is_a?(Time)
|
|
107
|
+
if arg.is_a?(Time)
|
|
90
108
|
if Timecop.active_support != false && arg.respond_to?(:in_time_zone)
|
|
91
109
|
arg.in_time_zone
|
|
92
110
|
else
|
|
@@ -117,17 +135,24 @@ class Timecop
|
|
|
117
135
|
end
|
|
118
136
|
end
|
|
119
137
|
end
|
|
120
|
-
|
|
138
|
+
|
|
121
139
|
def compute_dst_adjustment(time)
|
|
122
140
|
return 0 if !(time.dst? ^ Time.now.dst?)
|
|
123
141
|
return -1 * 60 * 60 if time.dst?
|
|
124
142
|
return 60 * 60
|
|
125
143
|
end
|
|
126
|
-
|
|
144
|
+
|
|
127
145
|
def compute_travel_offset
|
|
128
146
|
return nil if mock_type == :freeze
|
|
129
147
|
time - Time.now_without_mock_time
|
|
130
148
|
end
|
|
131
|
-
|
|
149
|
+
|
|
150
|
+
def times_are_equal_within_epsilon t1, t2, epsilon_in_seconds
|
|
151
|
+
(t1 - t2).abs < epsilon_in_seconds
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def time_klass
|
|
155
|
+
Time.respond_to?(:zone) ? Time.zone : Time
|
|
156
|
+
end
|
|
157
|
+
end
|
|
132
158
|
end
|
|
133
|
-
end
|
data/lib/timecop/timecop.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require 'singleton'
|
|
2
|
-
require
|
|
3
|
-
require
|
|
2
|
+
require File.join(File.dirname(__FILE__), "time_extensions")
|
|
3
|
+
require File.join(File.dirname(__FILE__), "time_stack_item")
|
|
4
4
|
|
|
5
5
|
# Timecop
|
|
6
6
|
# * Wrapper class for manipulating the extensions to the Time, Date, and DateTime objects
|
|
@@ -47,11 +47,9 @@ class Timecop
|
|
|
47
47
|
# which will lead to files being generated with the timestamp set by the Timecop.freeze call
|
|
48
48
|
# in your dev environment
|
|
49
49
|
#
|
|
50
|
-
# Returns the value of the block or
|
|
50
|
+
# Returns the value of the block if one is given, or the mocked time.
|
|
51
51
|
def freeze(*args, &block)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
block_given? ? val : nil
|
|
52
|
+
send_travel(:freeze, *args, &block)
|
|
55
53
|
end
|
|
56
54
|
|
|
57
55
|
# Allows you to run a block of code and "fake" a time throughout the execution of that block.
|
|
@@ -60,74 +58,103 @@ class Timecop
|
|
|
60
58
|
# * Note: Timecop.travel will not freeze time (as opposed to Timecop.freeze). This is a particularly
|
|
61
59
|
# good candidate for use in environment files in rails projects.
|
|
62
60
|
#
|
|
63
|
-
# Returns the value of the block or
|
|
61
|
+
# Returns the value of the block if one is given, or the mocked time.
|
|
64
62
|
def travel(*args, &block)
|
|
65
|
-
|
|
63
|
+
send_travel(:travel, *args, &block)
|
|
64
|
+
end
|
|
66
65
|
|
|
67
|
-
|
|
66
|
+
# Allows you to run a block of code and "scale" a time throughout the execution of that block.
|
|
67
|
+
# The first argument is a scaling factor, for example:
|
|
68
|
+
# Timecop.scale(2) do
|
|
69
|
+
# ... time will 'go' twice as fast here
|
|
70
|
+
# end
|
|
71
|
+
# See Timecop#freeze for exact usage of the other arguments
|
|
72
|
+
#
|
|
73
|
+
# Returns the value of the block if one is given, or the mocked time.
|
|
74
|
+
def scale(*args, &block)
|
|
75
|
+
send_travel(:scale, *args, &block)
|
|
68
76
|
end
|
|
69
77
|
|
|
70
78
|
def baseline
|
|
71
|
-
instance
|
|
79
|
+
instance.send(:baseline)
|
|
72
80
|
end
|
|
73
81
|
|
|
74
82
|
def baseline=(baseline)
|
|
75
|
-
instance
|
|
83
|
+
instance.send(:baseline=, baseline)
|
|
76
84
|
end
|
|
77
85
|
|
|
78
|
-
# Reverts back to system's Time.now, Date.today and DateTime.now (if it exists)
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
86
|
+
# Reverts back to system's Time.now, Date.today and DateTime.now (if it exists) permamently when
|
|
87
|
+
# no block argument is given, or temporarily reverts back to the system's time temporarily for
|
|
88
|
+
# the given block.
|
|
89
|
+
def return(&block)
|
|
90
|
+
if block_given?
|
|
91
|
+
instance.send(:return, &block)
|
|
92
|
+
else
|
|
93
|
+
instance.send(:unmock!)
|
|
94
|
+
nil
|
|
95
|
+
end
|
|
82
96
|
end
|
|
83
97
|
|
|
84
98
|
def return_to_baseline
|
|
85
|
-
instance
|
|
99
|
+
instance.send(:return_to_baseline)
|
|
86
100
|
Time.now
|
|
87
101
|
end
|
|
88
102
|
|
|
89
103
|
def top_stack_item #:nodoc:
|
|
90
|
-
instance
|
|
104
|
+
instance.instance_variable_get(:@_stack).last
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
private
|
|
108
|
+
def send_travel(mock_type, *args, &block)
|
|
109
|
+
val = instance.send(:travel, mock_type, *args, &block)
|
|
110
|
+
block_given? ? val : Time.now
|
|
91
111
|
end
|
|
92
112
|
end
|
|
93
113
|
|
|
94
|
-
|
|
114
|
+
private
|
|
95
115
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
116
|
+
def baseline=(baseline)
|
|
117
|
+
@baseline = baseline
|
|
118
|
+
@_stack << TimeStackItem.new(:travel, baseline)
|
|
119
|
+
end
|
|
100
120
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
121
|
+
def initialize #:nodoc:
|
|
122
|
+
@_stack = []
|
|
123
|
+
end
|
|
104
124
|
|
|
105
|
-
|
|
106
|
-
|
|
125
|
+
def travel(mock_type, *args, &block) #:nodoc:
|
|
126
|
+
stack_item = TimeStackItem.new(mock_type, *args)
|
|
107
127
|
|
|
108
|
-
|
|
109
|
-
@_stack << stack_item
|
|
128
|
+
@_stack << stack_item
|
|
110
129
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
@_stack.pop
|
|
117
|
-
end
|
|
130
|
+
if block_given?
|
|
131
|
+
begin
|
|
132
|
+
yield stack_item.time
|
|
133
|
+
ensure
|
|
134
|
+
@_stack.pop
|
|
118
135
|
end
|
|
119
136
|
end
|
|
137
|
+
end
|
|
120
138
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
139
|
+
def return(&block)
|
|
140
|
+
current_stack = @_stack
|
|
141
|
+
current_baseline = @baseline
|
|
142
|
+
unmock!
|
|
143
|
+
yield
|
|
144
|
+
@_stack = current_stack
|
|
145
|
+
@baseline = current_baseline
|
|
146
|
+
end
|
|
125
147
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
148
|
+
def unmock! #:nodoc:
|
|
149
|
+
@baseline = nil
|
|
150
|
+
@_stack = []
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def return_to_baseline
|
|
154
|
+
if @baseline
|
|
155
|
+
@_stack = [@_stack.shift]
|
|
156
|
+
else
|
|
157
|
+
unmock!
|
|
132
158
|
end
|
|
159
|
+
end
|
|
133
160
|
end
|
data/lib/timecop/version.rb
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
class Timecop
|
|
2
|
-
VERSION = "0.
|
|
3
|
-
end
|
|
2
|
+
VERSION = "0.6.0"
|
|
3
|
+
end
|
data/lib/timecop.rb
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
1
|
+
require File.join(File.dirname(__FILE__), "timecop", "timecop")
|
|
2
|
+
require File.join(File.dirname(__FILE__), "timecop", "version")
|
data/test/test_helper.rb
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
require 'date'
|
|
2
|
-
require
|
|
2
|
+
require File.join(File.dirname(__FILE__), "test_helper")
|
|
3
3
|
require File.join(File.dirname(__FILE__), '..', 'lib', 'timecop')
|
|
4
4
|
|
|
5
5
|
class TestTimeStackItem < Test::Unit::TestCase
|
|
6
|
-
|
|
7
6
|
def teardown
|
|
8
7
|
Timecop.active_support = nil
|
|
9
8
|
Timecop.return
|
|
10
9
|
end
|
|
11
|
-
|
|
10
|
+
|
|
12
11
|
def test_new_with_time
|
|
13
12
|
t = Time.now
|
|
14
13
|
y, m, d, h, min, s = t.year, t.month, t.day, t.hour, t.min, t.sec
|
|
15
14
|
stack_item = Timecop::TimeStackItem.new(:freeze, t)
|
|
15
|
+
|
|
16
16
|
assert_equal y, stack_item.year
|
|
17
17
|
assert_equal m, stack_item.month
|
|
18
18
|
assert_equal d, stack_item.day
|
|
@@ -25,6 +25,7 @@ class TestTimeStackItem < Test::Unit::TestCase
|
|
|
25
25
|
t = Time.new(2012, 7, 28, 20, 0)
|
|
26
26
|
y, m, d, h, min, s = t.year, t.month, t.day, t.hour, t.min, t.sec
|
|
27
27
|
stack_item = Timecop::TimeStackItem.new(:freeze, t)
|
|
28
|
+
|
|
28
29
|
assert_equal y, stack_item.year
|
|
29
30
|
assert_equal m, stack_item.month
|
|
30
31
|
assert_equal d, stack_item.day
|
|
@@ -32,11 +33,12 @@ class TestTimeStackItem < Test::Unit::TestCase
|
|
|
32
33
|
assert_equal min, stack_item.min
|
|
33
34
|
assert_equal s, stack_item.sec
|
|
34
35
|
end
|
|
35
|
-
|
|
36
|
+
|
|
36
37
|
def test_new_with_datetime_now
|
|
37
38
|
t = DateTime.now
|
|
38
39
|
y, m, d, h, min, s = t.year, t.month, t.day, t.hour, t.min, t.sec
|
|
39
40
|
stack_item = Timecop::TimeStackItem.new(:freeze, t)
|
|
41
|
+
|
|
40
42
|
assert_equal y, stack_item.year
|
|
41
43
|
assert_equal m, stack_item.month
|
|
42
44
|
assert_equal d, stack_item.day
|
|
@@ -44,19 +46,21 @@ class TestTimeStackItem < Test::Unit::TestCase
|
|
|
44
46
|
assert_equal min, stack_item.min
|
|
45
47
|
assert_equal s, stack_item.sec
|
|
46
48
|
end
|
|
47
|
-
|
|
49
|
+
|
|
48
50
|
def test_new_with_datetime_in_different_timezone
|
|
49
51
|
each_timezone do
|
|
50
52
|
t = DateTime.parse("2009-10-11 00:38:00 +0200")
|
|
51
53
|
stack_item = Timecop::TimeStackItem.new(:freeze, t)
|
|
54
|
+
|
|
52
55
|
assert_date_times_equal(t, stack_item.datetime)
|
|
53
56
|
end
|
|
54
57
|
end
|
|
55
|
-
|
|
58
|
+
|
|
56
59
|
def test_new_with_date
|
|
57
60
|
date = Date.today
|
|
58
61
|
y, m, d, h, min, s = date.year, date.month, date.day, 0, 0, 0
|
|
59
62
|
stack_item = Timecop::TimeStackItem.new(:freeze, date)
|
|
63
|
+
|
|
60
64
|
assert_equal y, stack_item.year
|
|
61
65
|
assert_equal m, stack_item.month
|
|
62
66
|
assert_equal d, stack_item.day
|
|
@@ -64,7 +68,7 @@ class TestTimeStackItem < Test::Unit::TestCase
|
|
|
64
68
|
assert_equal min, stack_item.min
|
|
65
69
|
assert_equal s, stack_item.sec
|
|
66
70
|
end
|
|
67
|
-
|
|
71
|
+
|
|
68
72
|
# Due to the nature of this test (calling Time.now once in this test and
|
|
69
73
|
# once in #new), this test may fail when two subsequent calls
|
|
70
74
|
# to Time.now return a different second.
|
|
@@ -72,6 +76,7 @@ class TestTimeStackItem < Test::Unit::TestCase
|
|
|
72
76
|
t = Time.now
|
|
73
77
|
y, m, d, h, min, s = t.year, t.month, t.day, t.hour, t.min, t.sec
|
|
74
78
|
stack_item = Timecop::TimeStackItem.new(:freeze, 0)
|
|
79
|
+
|
|
75
80
|
assert_equal y, stack_item.year
|
|
76
81
|
assert_equal m, stack_item.month
|
|
77
82
|
assert_equal d, stack_item.day
|
|
@@ -79,10 +84,11 @@ class TestTimeStackItem < Test::Unit::TestCase
|
|
|
79
84
|
assert_equal min, stack_item.min
|
|
80
85
|
assert_equal s, stack_item.sec
|
|
81
86
|
end
|
|
82
|
-
|
|
87
|
+
|
|
83
88
|
def test_new_with_individual_arguments
|
|
84
89
|
y, m, d, h, min, s = 2008, 10, 10, 10, 10, 10
|
|
85
90
|
stack_item = Timecop::TimeStackItem.new(:freeze, y, m, d, h, min, s)
|
|
91
|
+
|
|
86
92
|
assert_equal y, stack_item.year
|
|
87
93
|
assert_equal m, stack_item.month
|
|
88
94
|
assert_equal d, stack_item.day
|
|
@@ -90,88 +96,122 @@ class TestTimeStackItem < Test::Unit::TestCase
|
|
|
90
96
|
assert_equal min, stack_item.min
|
|
91
97
|
assert_equal s, stack_item.sec
|
|
92
98
|
end
|
|
93
|
-
|
|
99
|
+
|
|
94
100
|
def test_rational_to_utc_offset
|
|
95
101
|
assert_equal -14400, a_time_stack_item.send(:rational_to_utc_offset, Rational(-1, 6))
|
|
96
102
|
assert_equal -18000, a_time_stack_item.send(:rational_to_utc_offset, Rational(-5, 24))
|
|
97
103
|
assert_equal 0, a_time_stack_item.send(:rational_to_utc_offset, Rational(0, 1))
|
|
98
104
|
assert_equal 3600, a_time_stack_item.send(:rational_to_utc_offset, Rational(1, 24))
|
|
99
105
|
end
|
|
100
|
-
|
|
106
|
+
|
|
101
107
|
def test_utc_offset_to_rational
|
|
102
108
|
assert_equal Rational(-1, 6), a_time_stack_item.send(:utc_offset_to_rational, -14400)
|
|
103
109
|
assert_equal Rational(-5, 24), a_time_stack_item.send(:utc_offset_to_rational, -18000)
|
|
104
110
|
assert_equal Rational(0, 1), a_time_stack_item.send(:utc_offset_to_rational, 0)
|
|
105
111
|
assert_equal Rational(1, 24), a_time_stack_item.send(:utc_offset_to_rational, 3600)
|
|
106
112
|
end
|
|
107
|
-
|
|
108
|
-
# Ensure DST adjustment is calculated properly for DateTime's
|
|
113
|
+
|
|
109
114
|
def test_compute_dst_adjustment_for_dst_to_dst
|
|
110
115
|
Timecop.freeze(DateTime.parse("2009-10-1 00:38:00 -0400"))
|
|
111
116
|
t = DateTime.parse("2009-10-11 00:00:00 -0400")
|
|
112
117
|
tsi = Timecop::TimeStackItem.new(:freeze, t)
|
|
113
118
|
return if !(Time.now.dst? && tsi.time.dst?)
|
|
119
|
+
|
|
114
120
|
assert_equal 0, tsi.send(:dst_adjustment)
|
|
115
121
|
end
|
|
116
|
-
|
|
122
|
+
|
|
117
123
|
def test_compute_dst_adjustment_for_non_dst_to_non_dst
|
|
118
124
|
Timecop.freeze(DateTime.parse("2009-12-1 00:38:00 -0400"))
|
|
119
125
|
t = DateTime.parse("2009-12-11 00:00:00 -0400")
|
|
120
126
|
tsi = Timecop::TimeStackItem.new(:freeze, t)
|
|
121
127
|
return if Time.now.dst? || tsi.time.dst?
|
|
122
|
-
|
|
128
|
+
|
|
129
|
+
assert_equal 0, tsi.send(:dst_adjustment)
|
|
123
130
|
end
|
|
124
|
-
|
|
131
|
+
|
|
125
132
|
def test_compute_dst_adjustment_for_dst_to_non_dst
|
|
126
133
|
Timecop.freeze(DateTime.parse("2009-10-1 00:38:00 -0400"))
|
|
127
134
|
t = DateTime.parse("2009-12-11 00:00:00 -0400")
|
|
128
135
|
tsi = Timecop::TimeStackItem.new(:freeze, t)
|
|
129
136
|
return if !Time.now.dst? || tsi.time.dst?
|
|
137
|
+
|
|
130
138
|
assert_equal 60 * 60, tsi.send(:dst_adjustment)
|
|
131
139
|
end
|
|
132
|
-
|
|
140
|
+
|
|
133
141
|
def test_compute_dst_adjustment_for_non_dst_to_dst
|
|
134
142
|
Timecop.freeze(DateTime.parse("2009-12-1 00:38:00 -0400"))
|
|
135
143
|
t = DateTime.parse("2009-10-11 00:00:00 -0400")
|
|
136
144
|
tsi = Timecop::TimeStackItem.new(:freeze, t)
|
|
137
145
|
return if Time.now.dst? || !tsi.time.dst?
|
|
146
|
+
|
|
138
147
|
assert_equal -1 * 60 * 60, tsi.send(:dst_adjustment)
|
|
139
148
|
end
|
|
140
|
-
|
|
149
|
+
|
|
141
150
|
# Ensure DateTimes handle changing DST properly
|
|
142
151
|
def test_datetime_for_dst_to_non_dst
|
|
143
152
|
Timecop.freeze(DateTime.parse("2009-12-1 00:38:00 -0500"))
|
|
144
153
|
t = DateTime.parse("2009-10-11 00:00:00 -0400")
|
|
145
154
|
tsi = Timecop::TimeStackItem.new(:freeze, t)
|
|
155
|
+
|
|
146
156
|
assert_date_times_equal t, tsi.datetime
|
|
147
157
|
end
|
|
148
|
-
|
|
158
|
+
|
|
149
159
|
def test_datetime_for_non_dst_to_dst
|
|
150
160
|
Timecop.freeze(DateTime.parse("2009-10-11 00:00:00 -0400"))
|
|
151
161
|
t = DateTime.parse("2009-11-30 23:38:00 -0500")
|
|
152
162
|
tsi = Timecop::TimeStackItem.new(:freeze, t)
|
|
153
163
|
return if !tsi.time.dst?
|
|
164
|
+
|
|
154
165
|
assert_date_times_equal t, tsi.datetime
|
|
155
166
|
assert_equal Date.new(2009, 12, 1), tsi.date
|
|
156
167
|
end
|
|
157
|
-
|
|
158
|
-
# Ensure @travel_offset is set properly
|
|
168
|
+
|
|
159
169
|
def test_set_travel_offset_for_travel
|
|
160
|
-
# Timecop.freeze(2009, 10, 1, 0, 0, 0)
|
|
161
170
|
t_now = Time.now
|
|
162
171
|
t = Time.local(2009, 10, 1, 0, 0, 30)
|
|
163
172
|
expected_offset = t - t_now
|
|
164
173
|
tsi = Timecop::TimeStackItem.new(:travel, t)
|
|
174
|
+
|
|
165
175
|
assert_times_effectively_equal expected_offset, tsi.send(:travel_offset), 1, "Offset not calculated correctly"
|
|
166
176
|
end
|
|
167
|
-
|
|
177
|
+
|
|
168
178
|
def test_set_travel_offset_for_freeze
|
|
169
179
|
Timecop.freeze(2009, 10, 1, 0, 0, 0)
|
|
170
180
|
t = Time.local(2009, 10, 1, 0, 0, 30)
|
|
171
181
|
tsi = Timecop::TimeStackItem.new(:freeze, t)
|
|
182
|
+
|
|
172
183
|
assert_equal nil, tsi.send(:travel_offset)
|
|
173
184
|
end
|
|
174
185
|
|
|
186
|
+
def test_timezones
|
|
187
|
+
require 'active_support/all'
|
|
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_apply_dates
|
|
196
|
+
require 'active_support/all'
|
|
197
|
+
Time.zone = "Marshall Is."
|
|
198
|
+
time = Time.zone.local(2013,1,3)
|
|
199
|
+
|
|
200
|
+
Timecop.freeze(time) do
|
|
201
|
+
assert_equal time.to_date, Date.today
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def test_set_scaling_factor_for_scale
|
|
206
|
+
t_now = Time.now
|
|
207
|
+
t = Time.local(2009, 10, 1, 0, 0, 30)
|
|
208
|
+
expected_offset = t - t_now
|
|
209
|
+
tsi = Timecop::TimeStackItem.new(:scale, 4, t)
|
|
210
|
+
|
|
211
|
+
assert_times_effectively_equal expected_offset, tsi.send(:travel_offset), 1, "Offset not calculated correctly"
|
|
212
|
+
assert_equal tsi.send(:scaling_factor), 4, "Scaling factor not set"
|
|
213
|
+
end
|
|
214
|
+
|
|
175
215
|
def test_parse_string_date_with_active_support
|
|
176
216
|
date = '2012-01-02'
|
|
177
217
|
Time.expects(:parse).with(date).returns(Time.local(2012, 01, 02))
|
|
@@ -207,4 +247,21 @@ class TestTimeStackItem < Test::Unit::TestCase
|
|
|
207
247
|
Timecop.freeze(Date.new(2012, 6, 9))
|
|
208
248
|
end
|
|
209
249
|
end
|
|
250
|
+
|
|
251
|
+
def test_nsecs_are_set
|
|
252
|
+
time = Time.now
|
|
253
|
+
Timecop.freeze time
|
|
254
|
+
assert_equal time, Time.now
|
|
255
|
+
assert_equal time.nsec, Time.now.nsec if (Time.now.respond_to?(:nsec))
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
def test_time_with_different_timezone
|
|
259
|
+
require 'active_support/all'
|
|
260
|
+
|
|
261
|
+
Time.zone = "Tokyo"
|
|
262
|
+
t = Time.now
|
|
263
|
+
Timecop.freeze(t) do
|
|
264
|
+
assert_times_effectively_equal t, Time.now
|
|
265
|
+
end
|
|
266
|
+
end
|
|
210
267
|
end
|
data/test/timecop_test.rb
CHANGED
|
@@ -1,27 +1,22 @@
|
|
|
1
1
|
require 'date'
|
|
2
|
-
require
|
|
2
|
+
require File.join(File.dirname(__FILE__), "test_helper")
|
|
3
3
|
require File.join(File.dirname(__FILE__), '..', 'lib', 'timecop')
|
|
4
4
|
|
|
5
5
|
class TestTimecop < Test::Unit::TestCase
|
|
6
|
-
|
|
7
|
-
def setup
|
|
8
|
-
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
# just in case...let's really make sure that Timecop is disabled between tests...
|
|
12
6
|
def teardown
|
|
13
7
|
Timecop.return
|
|
14
8
|
end
|
|
15
9
|
|
|
16
10
|
def test_freeze_changes_and_resets_time
|
|
17
|
-
# depending on how we're invoked (individually or via the rake test suite)
|
|
18
11
|
assert !Time.respond_to?(:zone) || Time.zone.nil?
|
|
19
12
|
|
|
20
13
|
t = Time.local(2008, 10, 10, 10, 10, 10)
|
|
21
14
|
assert_not_equal t, Time.now
|
|
15
|
+
|
|
22
16
|
Timecop.freeze(2008, 10, 10, 10, 10, 10) do
|
|
23
17
|
assert_equal t, Time.now
|
|
24
18
|
end
|
|
19
|
+
|
|
25
20
|
assert_not_equal t, Time.now
|
|
26
21
|
end
|
|
27
22
|
|
|
@@ -68,6 +63,7 @@ class TestTimecop < Test::Unit::TestCase
|
|
|
68
63
|
custom_timeklass = Class.new(Time) do
|
|
69
64
|
def custom_format_method() strftime('%F') end
|
|
70
65
|
end
|
|
66
|
+
|
|
71
67
|
Timecop.freeze(2008, 10, 10, 10, 10, 10) do
|
|
72
68
|
assert custom_timeklass.now.is_a? custom_timeklass
|
|
73
69
|
assert Time.now.eql? custom_timeklass.now
|
|
@@ -80,6 +76,7 @@ class TestTimecop < Test::Unit::TestCase
|
|
|
80
76
|
custom_dateklass = Class.new(Date) do
|
|
81
77
|
def custom_format_method() strftime('%F') end
|
|
82
78
|
end
|
|
79
|
+
|
|
83
80
|
Timecop.freeze(2008, 10, 10, 10, 10, 10) do
|
|
84
81
|
assert custom_dateklass.today.is_a? custom_dateklass
|
|
85
82
|
assert Date.today.eql? custom_dateklass.today
|
|
@@ -92,6 +89,7 @@ class TestTimecop < Test::Unit::TestCase
|
|
|
92
89
|
custom_datetimeklass = Class.new(DateTime) do
|
|
93
90
|
def custom_format_method() strftime('%F') end
|
|
94
91
|
end
|
|
92
|
+
|
|
95
93
|
Timecop.freeze(2008, 10, 10, 10, 10, 10) do
|
|
96
94
|
assert custom_datetimeklass.now.is_a? custom_datetimeklass
|
|
97
95
|
assert DateTime.now.eql? custom_datetimeklass.now
|
|
@@ -119,6 +117,7 @@ class TestTimecop < Test::Unit::TestCase
|
|
|
119
117
|
assert_date_times_equal DateTime.new(2008, 10, 10, 10, 10, 10, local_offset), DateTime.now
|
|
120
118
|
assert_equal Date.new(2008, 10, 10), Date.today
|
|
121
119
|
end
|
|
120
|
+
|
|
122
121
|
assert_not_equal t, Time.now
|
|
123
122
|
assert_not_equal DateTime.new(2008, 10, 10, 10, 10, 10, local_offset), DateTime.now
|
|
124
123
|
assert_not_equal Date.new(2008, 10, 10), Date.today
|
|
@@ -133,7 +132,6 @@ class TestTimecop < Test::Unit::TestCase
|
|
|
133
132
|
Timecop.freeze(t) do
|
|
134
133
|
assert_date_times_equal t, DateTime.now
|
|
135
134
|
end
|
|
136
|
-
# Undo the original freeze
|
|
137
135
|
Timecop.return
|
|
138
136
|
end
|
|
139
137
|
end
|
|
@@ -250,6 +248,21 @@ class TestTimecop < Test::Unit::TestCase
|
|
|
250
248
|
end
|
|
251
249
|
end
|
|
252
250
|
|
|
251
|
+
def test_scaling_keeps_time_moving_at_an_accelerated_rate
|
|
252
|
+
t = Time.local(2008, 10, 10, 10, 10, 10)
|
|
253
|
+
Timecop.scale(4, t) do
|
|
254
|
+
start = Time.now
|
|
255
|
+
assert_times_effectively_equal start, t, 1, "Looks like we failed to actually travel time"
|
|
256
|
+
sleep(0.25)
|
|
257
|
+
assert_times_effectively_equal Time.at((start + 4*0.25).to_f), Time.now, 0.25, "Looks like time is not moving at 4x"
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
def test_scaling_returns_now_if_no_block_given
|
|
262
|
+
t = Time.local(2008, 10, 10, 10, 10, 10)
|
|
263
|
+
assert_times_effectively_equal t, Timecop.scale(4, t)
|
|
264
|
+
end
|
|
265
|
+
|
|
253
266
|
def test_freeze_with_utc_time
|
|
254
267
|
each_timezone do
|
|
255
268
|
t = Time.utc(2008, 10, 10, 10, 10, 10)
|
|
@@ -324,9 +337,22 @@ class TestTimecop < Test::Unit::TestCase
|
|
|
324
337
|
assert_nil Time.send(:mock_time)
|
|
325
338
|
end
|
|
326
339
|
|
|
327
|
-
def
|
|
340
|
+
def test_travel_time_returns_now_if_no_block_given
|
|
328
341
|
t_future = Time.local(2030, 10, 10, 10, 10, 10)
|
|
329
|
-
|
|
342
|
+
assert_times_effectively_equal t_future, Timecop.travel(t_future)
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
def test_return_temporarily_returns_to_current_time_in_given_block
|
|
346
|
+
time_after_travel = Time.local(1990, 7, 16)
|
|
347
|
+
now = Time.now
|
|
348
|
+
|
|
349
|
+
Timecop.travel(time_after_travel)
|
|
350
|
+
|
|
351
|
+
assert_times_effectively_equal(time_after_travel, Time.now)
|
|
352
|
+
Timecop.return do
|
|
353
|
+
assert_times_effectively_equal(now, Time.now)
|
|
354
|
+
end
|
|
355
|
+
assert_times_effectively_equal(time_after_travel, Time.now)
|
|
330
356
|
end
|
|
331
357
|
|
|
332
358
|
def test_travel_time_with_block_returns_the_value_of_the_block
|
|
@@ -337,9 +363,9 @@ class TestTimecop < Test::Unit::TestCase
|
|
|
337
363
|
assert_equal expected, actual
|
|
338
364
|
end
|
|
339
365
|
|
|
340
|
-
def
|
|
366
|
+
def test_freeze_time_returns_now_if_no_block_given
|
|
341
367
|
t_future = Time.local(2030, 10, 10, 10, 10, 10)
|
|
342
|
-
|
|
368
|
+
assert_times_effectively_equal t_future, Timecop.freeze(t_future)
|
|
343
369
|
end
|
|
344
370
|
|
|
345
371
|
def test_freeze_time_with_block_returns_the_value_of_the_block
|
|
@@ -403,4 +429,10 @@ class TestTimecop < Test::Unit::TestCase
|
|
|
403
429
|
assert_equal date, Time.now
|
|
404
430
|
assert_equal date, Time.new
|
|
405
431
|
end
|
|
432
|
+
|
|
433
|
+
def test_not_callable_send_travel
|
|
434
|
+
assert_raise NoMethodError do
|
|
435
|
+
Timecop.send_travel(:travel, Time.now - 100)
|
|
436
|
+
end
|
|
437
|
+
end
|
|
406
438
|
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.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date:
|
|
13
|
+
date: 2013-03-08 00:00:00.000000000 Z
|
|
14
14
|
dependencies: []
|
|
15
15
|
description: A gem providing "time travel" and "time freezing" capabilities, making
|
|
16
16
|
it dead simple to test time-dependent code. It provides a unified method to mock
|
|
@@ -22,7 +22,6 @@ extra_rdoc_files:
|
|
|
22
22
|
- LICENSE
|
|
23
23
|
- README.markdown
|
|
24
24
|
files:
|
|
25
|
-
- History.rdoc
|
|
26
25
|
- LICENSE
|
|
27
26
|
- README.markdown
|
|
28
27
|
- Rakefile
|
|
@@ -37,8 +36,9 @@ files:
|
|
|
37
36
|
- test/timecop_test.rb
|
|
38
37
|
- test/timecop_without_date_test.rb
|
|
39
38
|
- test/timecop_without_date_but_with_time_test.rb
|
|
40
|
-
homepage:
|
|
41
|
-
licenses:
|
|
39
|
+
homepage: https://github.com/travisjeffery/timecop
|
|
40
|
+
licenses:
|
|
41
|
+
- MIT
|
|
42
42
|
post_install_message:
|
|
43
43
|
rdoc_options:
|
|
44
44
|
- --charset=UTF-8
|
|
@@ -57,8 +57,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
57
57
|
- !ruby/object:Gem::Version
|
|
58
58
|
version: '0'
|
|
59
59
|
requirements: []
|
|
60
|
-
rubyforge_project:
|
|
61
|
-
rubygems_version: 1.8.
|
|
60
|
+
rubyforge_project: timecop
|
|
61
|
+
rubygems_version: 1.8.23
|
|
62
62
|
signing_key:
|
|
63
63
|
specification_version: 3
|
|
64
64
|
summary: A gem providing "time travel" and "time freezing" capabilities, making it
|
data/History.rdoc
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
=== 0.5.0 / 2012-09-12
|
|
2
|
-
|
|
3
|
-
* Maintenance
|
|
4
|
-
* Timecop#travel, Timecop#freeze blocks return nil or block value
|
|
5
|
-
|
|
6
|
-
=== 0.4.6 / 2012-09-05
|
|
7
|
-
|
|
8
|
-
* Maintenance
|
|
9
|
-
* Fix rounding support for Ruby < 1.9
|
|
10
|
-
|
|
11
|
-
=== 0.4.5 / 2012-08-09
|
|
12
|
-
|
|
13
|
-
* Maintenance
|
|
14
|
-
* Subclasses of Time/Date/DateTime now return proper instances
|
|
15
|
-
|
|
16
|
-
=== 0.4.4 / 2012-07-29
|
|
17
|
-
|
|
18
|
-
* Maintenance
|
|
19
|
-
* Can now configure Timecop to not use ActiveSupport by setting Timecop.active_support = false
|
|
20
|
-
|
|
21
|
-
=== 0.4.3 / 2012-07-27
|
|
22
|
-
|
|
23
|
-
* Maintenance
|
|
24
|
-
* Fix alias of Time#new/Time#now when Time#new given with args
|
|
25
|
-
|
|
26
|
-
=== 0.4.2 / 2012-07-27
|
|
27
|
-
|
|
28
|
-
* Maintenance
|
|
29
|
-
* Mock Time#new the same as Time#now since they're synonyms
|
|
30
|
-
* Set default arg in parsing to 2000
|
|
31
|
-
* Time.freeze defaults to Time#now
|
|
32
|
-
* Use Time#parse is available to parse Time's given as strings
|
|
33
|
-
* Add ActiveSupport Time.zone support
|
|
34
|
-
* Stop DateTime from losing precision after traveling
|
|
35
|
-
|
|
36
|
-
=== 0.3.5 / 2010-06-07
|
|
37
|
-
|
|
38
|
-
* Maintenance
|
|
39
|
-
* Return a cloned time instance in order to support the destructive methods #gmt, #utc and #localtime
|
|
40
|
-
* Don't use full path requires where unnecessary
|
|
41
|
-
|
|
42
|
-
=== 0.3.4 / 2009-12-07
|
|
43
|
-
|
|
44
|
-
* Maintenance
|
|
45
|
-
* Fix various timezone-related issues. Notably, when traveling to a DateTime
|
|
46
|
-
instance specified in a non-local timezone, convert provided DateTime
|
|
47
|
-
instance to a local instance and return that from DateTime.now.
|
|
48
|
-
Code contributed by Michaël Witrant [piglop]
|
|
49
|
-
* Fix bug that would not allow Timecop to be used when Ruby's 'date'
|
|
50
|
-
library had not been previously loaded.
|
|
51
|
-
Code contributed by Tuomas Kareinen [tuomas]
|
|
52
|
-
* Fix bug when traveling to a DateTime across a DST boundary that
|
|
53
|
-
resulted in DateTime's being off by an hour.
|
|
54
|
-
* Migrate argument parsing into Timecop::TimeStackItem to reduce the
|
|
55
|
-
responsibility of the Timecop class.
|
|
56
|
-
|
|
57
|
-
=== 0.3.3 2009-10-30
|
|
58
|
-
|
|
59
|
-
* Revoked due to regression.
|
|
60
|
-
|
|
61
|
-
=== 0.3.2 / 2009-10-24
|
|
62
|
-
|
|
63
|
-
* Revoked due to regression.
|
|
64
|
-
|
|
65
|
-
=== 0.3.1 / 2009-09-30
|
|
66
|
-
|
|
67
|
-
* Maintenance
|
|
68
|
-
* DRY up the Timecop class internals.
|
|
69
|
-
|
|
70
|
-
=== 0.3.0 / 2009-09-20
|
|
71
|
-
|
|
72
|
-
* API
|
|
73
|
-
* Completely remove Timecop#unset_all (deprecated by Timecop#return in 0.2.0)
|
|
74
|
-
* Return Time.now from #freeze, #travel and #return -- code contributed by Keith Bennett [keithrbennett]
|
|
75
|
-
|
|
76
|
-
* Maintenance
|
|
77
|
-
* Fix bug that left Time#mock_time set in some instances
|
|
78
|
-
* Upped build dependency to jeweler ~> 1.2.1
|
|
79
|
-
* Don't pollute top-level namespace with classes/constants
|
|
80
|
-
|
|
81
|
-
* Documentation
|
|
82
|
-
* Clearer examples in the README, better description in the gemspec
|
|
83
|
-
* Improve RDoc
|
|
84
|
-
|
|
85
|
-
=== 0.2.1 / 2009-03-06
|
|
86
|
-
* API Changes
|
|
87
|
-
|
|
88
|
-
* Introduced a 5th style of arguments to be passed into #travel and #freeze. Now, if you pass in a single integer value,
|
|
89
|
-
it will be interpreted as a relative offset in seconds from the current Time.now. Previously this was interpreted as
|
|
90
|
-
only the year, similar to calling Time.local(2008) --> Jan. 1, 2008. This is no longer the case.
|
|
91
|
-
|
|
92
|
-
* Documentation
|
|
93
|
-
|
|
94
|
-
* Moved to Textile for the README.
|
|
95
|
-
|
|
96
|
-
* Added documentation for the new feature, and fixed a few typos.
|
|
97
|
-
|
|
98
|
-
=== 0.2.0 / 2008-12-23
|
|
99
|
-
|
|
100
|
-
* API Changes
|
|
101
|
-
|
|
102
|
-
* Timecop#travel no longer freezes time. Rather, it computes the current offset between the new "now" and the real "now", and
|
|
103
|
-
returns times as if Time had continued to move forward
|
|
104
|
-
|
|
105
|
-
* Timecop#freeze now behaves exactly as the old Timecop#travel behaved. Unless you depended on the actual freezing of time
|
|
106
|
-
(which I think would be rare), you should be able to continue to use #travel without worry.
|
|
107
|
-
|
|
108
|
-
* Timecop#return is now exposed (previously Timecop#unset_all, but not well advertised). It will completely unmock time,
|
|
109
|
-
and will probably be rarely used outside of the actual implementation of this library.
|
|
110
|
-
|
|
111
|
-
* More Test Coverage
|
|
112
|
-
|
|
113
|
-
* Tests now explicitly cover the cases when the Date and DateTime objects are not loaded, and ensures proper functionality
|
|
114
|
-
in their absence and existence.
|
|
115
|
-
|
|
116
|
-
* Still haven't done regression testing against anything other than a few version of 1.8.6 (including REE). We should
|
|
117
|
-
probably try to get this tested on both 1.8.7 and 1.9.1.
|
|
118
|
-
|
|
119
|
-
* Documentation
|
|
120
|
-
|
|
121
|
-
* Fixed up a lot of the poorly-formatted rdoc syntax. The public API should now be properly published in the rdoc,
|
|
122
|
-
and the internals are omitted.
|
|
123
|
-
|
|
124
|
-
=== 0.1.0 / 2008-11-09
|
|
125
|
-
|
|
126
|
-
* Initial Feature Set
|
|
127
|
-
|
|
128
|
-
* Temporarily (or permanently if you prefer) change the concept of Time.now, DateTime.now (if defined), and Date.today (if defined)
|
|
129
|
-
* Timecop#travel api allows an argument to be passed in as one of: 1) Time instance, 2) DateTime instance, 3) Date instance,
|
|
130
|
-
4) individual arguments (year, month, day, hour, minute, second)
|
|
131
|
-
* Nested calls to Timecop#travel are supported -- each block will maintain it's interpretation of now.
|
|
132
|
-
|