timecop 0.6.1 → 0.8.1
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 +22 -14
- data/Rakefile +10 -4
- data/lib/timecop/time_extensions.rb +81 -47
- data/lib/timecop/time_stack_item.rb +15 -36
- data/lib/timecop/timecop.rb +25 -3
- data/lib/timecop/version.rb +1 -1
- data/test/test_helper.rb +21 -21
- data/test/time_stack_item_test.rb +87 -73
- data/test/timecop_test.rb +140 -30
- data/test/timecop_without_date_but_with_time_test.rb +4 -8
- data/test/timecop_without_date_test.rb +21 -22
- metadata +11 -13
- data/test/run_tests.sh +0 -6
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: bfc685225a22109f897b68e3174608a4b6a16def
|
|
4
|
+
data.tar.gz: 66aee6ccc9dfd424502c3f3f149c175af3fa3fbc
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: ac084a1428c7b528faa70aa321b1cb9db1f9f3f8eb45e4a94777f15b915662fc60ba9208091837903348348a1c902c109649aa7a471819cbec7ea1e0d8c1a377
|
|
7
|
+
data.tar.gz: 14082a5cba36b7f5238455d884025c5f9ce01ca0b81073f9b9860220286d13db10cce76b3da38465fb585976fd29782a1e0d81913d699814e4505790446e03b7
|
data/README.markdown
CHANGED
|
@@ -2,16 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
[](http://travis-ci.org/travisjeffery/timecop)
|
|
4
4
|
|
|
5
|
-
- Source[http://github.com/travisjeffery/timecop]
|
|
6
|
-
- Documentation[http://johntrupiano.rubyforge.org/timecop]
|
|
7
|
-
|
|
8
5
|
## DESCRIPTION
|
|
9
6
|
|
|
10
7
|
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, and DateTime.now in a single call.
|
|
11
8
|
|
|
12
9
|
## INSTALL
|
|
13
10
|
|
|
14
|
-
|
|
11
|
+
`gem install timecop`
|
|
15
12
|
|
|
16
13
|
## FEATURES
|
|
17
14
|
|
|
@@ -49,12 +46,13 @@ describe "some set of tests to mock" do
|
|
|
49
46
|
before do
|
|
50
47
|
Timecop.freeze(Time.local(1990))
|
|
51
48
|
end
|
|
52
|
-
|
|
49
|
+
|
|
53
50
|
after do
|
|
54
51
|
Timecop.return
|
|
55
52
|
end
|
|
56
53
|
|
|
57
|
-
it "should do blah blah blah"
|
|
54
|
+
it "should do blah blah blah" do
|
|
55
|
+
end
|
|
58
56
|
end
|
|
59
57
|
```
|
|
60
58
|
|
|
@@ -62,7 +60,7 @@ Set the time for the test environment of a rails app -- this is particularly
|
|
|
62
60
|
helpful if your whole application is time-sensitive. It allows you to build
|
|
63
61
|
your test data at a single point in time, and to move in/out of that time as
|
|
64
62
|
appropriate (within your tests)
|
|
65
|
-
|
|
63
|
+
|
|
66
64
|
in config/environments/test.rb
|
|
67
65
|
|
|
68
66
|
```ruby
|
|
@@ -111,19 +109,29 @@ Time.now
|
|
|
111
109
|
# => 2012-09-21 06:22:59 -0500
|
|
112
110
|
```
|
|
113
111
|
|
|
114
|
-
See #42 for more information, thanks to Ken Mayer, David Holcomb, and Pivotal Labs.
|
|
112
|
+
See [#42](https://github.com/travisjeffery/timecop/pull/42) for more information, thanks to Ken Mayer, David Holcomb, and Pivotal Labs.
|
|
115
113
|
|
|
116
|
-
|
|
114
|
+
### Timecop.safe_mode
|
|
117
115
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
116
|
+
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.
|
|
117
|
+
|
|
118
|
+
``` ruby
|
|
119
|
+
# turn on safe mode
|
|
120
|
+
Timecop.safe_mode = true
|
|
121
|
+
|
|
122
|
+
# check if you are in safe mode
|
|
123
|
+
Timecop.safe_mode?
|
|
124
|
+
# => true
|
|
125
|
+
|
|
126
|
+
# using method without block
|
|
127
|
+
Timecop.freeze
|
|
128
|
+
# => Timecop::SafeModeException: Safe mode is enabled, only calls passing a block are allowed.
|
|
129
|
+
```
|
|
122
130
|
|
|
123
131
|
## Contribute
|
|
124
132
|
|
|
125
133
|
timecop is maintained by [travisjeffery](http://github.com/travisjeffery), and
|
|
126
|
-
was created by [jtrupiano](https://github.com/jtrupiano).
|
|
134
|
+
was created by [jtrupiano](https://github.com/jtrupiano).
|
|
127
135
|
|
|
128
136
|
Here's the most direct way to get your work merged into the project.
|
|
129
137
|
|
data/Rakefile
CHANGED
|
@@ -3,8 +3,6 @@ require 'bundler/gem_tasks'
|
|
|
3
3
|
require 'rake/testtask'
|
|
4
4
|
require 'rdoc/task'
|
|
5
5
|
|
|
6
|
-
$LOAD_PATH.unshift("lib")
|
|
7
|
-
|
|
8
6
|
Rake::RDocTask.new do |rdoc|
|
|
9
7
|
if File.exist?('VERSION')
|
|
10
8
|
version = File.read('VERSION')
|
|
@@ -20,8 +18,16 @@ Rake::RDocTask.new do |rdoc|
|
|
|
20
18
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
21
19
|
end
|
|
22
20
|
|
|
23
|
-
task :test do
|
|
24
|
-
|
|
21
|
+
task :test do
|
|
22
|
+
failed = Dir["test/*_test.rb"].map do |test|
|
|
23
|
+
command = "ruby #{test}"
|
|
24
|
+
puts
|
|
25
|
+
puts command
|
|
26
|
+
command unless system(command)
|
|
27
|
+
end.compact
|
|
28
|
+
if failed.any?
|
|
29
|
+
abort "#{failed.count} Tests failed\n#{failed.join("\n")}"
|
|
30
|
+
end
|
|
25
31
|
end
|
|
26
32
|
|
|
27
33
|
desc 'Default: run tests'
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require 'time'
|
|
2
|
+
require 'date'
|
|
1
3
|
|
|
2
4
|
class Time #:nodoc:
|
|
3
5
|
class << self
|
|
@@ -5,77 +7,109 @@ class Time #:nodoc:
|
|
|
5
7
|
mocked_time_stack_item = Timecop.top_stack_item
|
|
6
8
|
mocked_time_stack_item.nil? ? nil : mocked_time_stack_item.time(self)
|
|
7
9
|
end
|
|
8
|
-
|
|
10
|
+
|
|
9
11
|
alias_method :now_without_mock_time, :now
|
|
10
12
|
|
|
11
13
|
def now_with_mock_time
|
|
12
14
|
mock_time || now_without_mock_time
|
|
13
15
|
end
|
|
14
|
-
|
|
16
|
+
|
|
15
17
|
alias_method :now, :now_with_mock_time
|
|
16
18
|
|
|
17
19
|
alias_method :new_without_mock_time, :new
|
|
18
20
|
|
|
19
21
|
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
|
|
22
|
+
args.size <= 0 ? now : new_without_mock_time(*args)
|
|
26
23
|
end
|
|
27
24
|
|
|
28
25
|
alias_method :new, :new_with_mock_time
|
|
29
26
|
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class Date #:nodoc:
|
|
30
|
+
WEEKDAYS = {
|
|
31
|
+
"sunday" => 0,
|
|
32
|
+
"monday" => 1,
|
|
33
|
+
"tuesday" => 2,
|
|
34
|
+
"wednesday" => 3,
|
|
35
|
+
"thursday" => 4,
|
|
36
|
+
"friday" => 5,
|
|
37
|
+
"saturday" => 6
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
class << self
|
|
41
|
+
def mock_date
|
|
42
|
+
mocked_time_stack_item = Timecop.top_stack_item
|
|
43
|
+
mocked_time_stack_item.nil? ? nil : mocked_time_stack_item.date(self)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
alias_method :today_without_mock_date, :today
|
|
47
|
+
|
|
48
|
+
def today_with_mock_date
|
|
49
|
+
mock_date || today_without_mock_date
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
alias_method :today, :today_with_mock_date
|
|
53
|
+
|
|
54
|
+
alias_method :strptime_without_mock_date, :strptime
|
|
55
|
+
|
|
56
|
+
def strptime_with_mock_date(str = '-4712-01-01', fmt = '%F', start = Date::ITALY)
|
|
57
|
+
unless start == Date::ITALY
|
|
58
|
+
raise ArgumentError, "Timecop's #{self}::#{__method__} only " +
|
|
59
|
+
"supports Date::ITALY for the start argument."
|
|
38
60
|
end
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
61
|
+
|
|
62
|
+
Time.strptime(str, fmt).to_date
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
alias_method :strptime, :strptime_with_mock_date
|
|
66
|
+
|
|
67
|
+
def parse_with_mock_date(*args)
|
|
68
|
+
str = args.first
|
|
69
|
+
if str && WEEKDAYS.keys.include?(str.downcase)
|
|
70
|
+
offset = WEEKDAYS[str.downcase] - Date.today.wday
|
|
71
|
+
|
|
72
|
+
Date.today + offset
|
|
73
|
+
else
|
|
74
|
+
parse_without_mock_date(*args)
|
|
44
75
|
end
|
|
45
|
-
|
|
46
|
-
alias_method :today, :today_with_mock_date
|
|
47
76
|
end
|
|
77
|
+
|
|
78
|
+
alias_method :parse_without_mock_date, :parse
|
|
79
|
+
alias_method :parse, :parse_with_mock_date
|
|
80
|
+
|
|
48
81
|
end
|
|
49
82
|
end
|
|
50
83
|
|
|
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
|
|
84
|
+
class DateTime #:nodoc:
|
|
85
|
+
class << self
|
|
86
|
+
def mock_time
|
|
87
|
+
mocked_time_stack_item = Timecop.top_stack_item
|
|
88
|
+
mocked_time_stack_item.nil? ? nil : mocked_time_stack_item.datetime(self)
|
|
89
|
+
end
|
|
66
90
|
|
|
67
|
-
|
|
91
|
+
def now_with_mock_time
|
|
92
|
+
mock_time || now_without_mock_time
|
|
68
93
|
end
|
|
69
|
-
end
|
|
70
94
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
95
|
+
alias_method :now_without_mock_time, :now
|
|
96
|
+
|
|
97
|
+
alias_method :now, :now_with_mock_time
|
|
98
|
+
|
|
99
|
+
def parse_with_mock_date(*args)
|
|
100
|
+
str = args.first
|
|
101
|
+
if str && Date::WEEKDAYS.keys.include?(str.downcase)
|
|
102
|
+
offset = Date::WEEKDAYS[str.downcase] - DateTime.now.wday
|
|
103
|
+
|
|
104
|
+
parsed_weekday =(DateTime.now + offset)
|
|
105
|
+
|
|
106
|
+
DateTime.new(parsed_weekday.year, parsed_weekday.month, parsed_weekday.day, 0, 0, 0, 0)
|
|
107
|
+
else
|
|
108
|
+
parse_without_mock_date(*args)
|
|
78
109
|
end
|
|
79
110
|
end
|
|
111
|
+
|
|
112
|
+
alias_method :parse_without_mock_date, :parse
|
|
113
|
+
alias_method :parse, :parse_with_mock_date
|
|
80
114
|
end
|
|
81
115
|
end
|
|
@@ -6,12 +6,12 @@ class Timecop
|
|
|
6
6
|
|
|
7
7
|
def initialize(mock_type, *args)
|
|
8
8
|
raise "Unknown mock_type #{mock_type}" unless [:freeze, :travel, :scale].include?(mock_type)
|
|
9
|
+
@travel_offset = @scaling_factor = nil
|
|
9
10
|
@scaling_factor = args.shift if mock_type == :scale
|
|
10
11
|
@mock_type = mock_type
|
|
11
12
|
@time = parse_time(*args)
|
|
12
13
|
@time_was = Time.now_without_mock_time
|
|
13
14
|
@travel_offset = compute_travel_offset
|
|
14
|
-
@dst_adjustment = compute_dst_adjustment(@time)
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def year
|
|
@@ -50,21 +50,19 @@ class Timecop
|
|
|
50
50
|
@scaling_factor
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
-
def time(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
time =
|
|
58
|
-
rescue
|
|
59
|
-
time = klass.at(@time.to_f)
|
|
53
|
+
def time(time_klass = Time) #:nodoc:
|
|
54
|
+
if @time.respond_to?(:in_time_zone)
|
|
55
|
+
time = time_klass.at(@time.dup.utc.to_r)
|
|
56
|
+
else
|
|
57
|
+
time = time_klass.at(@time)
|
|
60
58
|
end
|
|
61
59
|
|
|
62
60
|
if travel_offset.nil?
|
|
63
61
|
time
|
|
64
62
|
elsif scaling_factor.nil?
|
|
65
|
-
|
|
63
|
+
time_klass.at((Time.now_without_mock_time + travel_offset).to_f)
|
|
66
64
|
else
|
|
67
|
-
|
|
65
|
+
time_klass.at(scaled_time)
|
|
68
66
|
end
|
|
69
67
|
end
|
|
70
68
|
|
|
@@ -77,21 +75,14 @@ class Timecop
|
|
|
77
75
|
end
|
|
78
76
|
|
|
79
77
|
def datetime(datetime_klass = DateTime)
|
|
80
|
-
our_offset = utc_offset + dst_adjustment
|
|
81
|
-
|
|
82
78
|
if Float.method_defined?(:to_r)
|
|
83
79
|
fractions_of_a_second = time.to_f % 1
|
|
84
|
-
datetime_klass.new(year, month, day, hour, min,
|
|
80
|
+
datetime_klass.new(year, month, day, hour, min, (fractions_of_a_second + sec), utc_offset_to_rational(utc_offset))
|
|
85
81
|
else
|
|
86
|
-
|
|
87
|
-
datetime_klass.new(year, month, day, hour, min, sec, utc_offset_to_rational(our_offset))
|
|
82
|
+
datetime_klass.new(year, month, day, hour, min, sec, utc_offset_to_rational(utc_offset))
|
|
88
83
|
end
|
|
89
84
|
end
|
|
90
85
|
|
|
91
|
-
def dst_adjustment
|
|
92
|
-
@dst_adjustment
|
|
93
|
-
end
|
|
94
|
-
|
|
95
86
|
private
|
|
96
87
|
|
|
97
88
|
def rational_to_utc_offset(rational)
|
|
@@ -105,23 +96,17 @@ class Timecop
|
|
|
105
96
|
def parse_time(*args)
|
|
106
97
|
arg = args.shift
|
|
107
98
|
if arg.is_a?(Time)
|
|
108
|
-
|
|
109
|
-
arg.in_time_zone
|
|
110
|
-
else
|
|
111
|
-
arg.getlocal
|
|
112
|
-
end
|
|
99
|
+
arg
|
|
113
100
|
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)
|
|
101
|
+
time_klass.at(arg.to_time.to_f).getlocal
|
|
117
102
|
elsif Object.const_defined?(:Date) && arg.is_a?(Date)
|
|
118
103
|
time_klass.local(arg.year, arg.month, arg.day, 0, 0, 0)
|
|
119
|
-
elsif args.empty? && arg.kind_of?(Integer)
|
|
104
|
+
elsif args.empty? && (arg.kind_of?(Integer) || arg.kind_of?(Float))
|
|
120
105
|
Time.now + arg
|
|
121
106
|
elsif arg.nil?
|
|
122
107
|
Time.now
|
|
123
108
|
else
|
|
124
|
-
if arg.is_a?(String) &&
|
|
109
|
+
if arg.is_a?(String) && Time.respond_to?(:parse)
|
|
125
110
|
Time.parse(arg)
|
|
126
111
|
else
|
|
127
112
|
# we'll just assume it's a list of y/m/d/h/m/s
|
|
@@ -136,12 +121,6 @@ class Timecop
|
|
|
136
121
|
end
|
|
137
122
|
end
|
|
138
123
|
|
|
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
124
|
def compute_travel_offset
|
|
146
125
|
return nil if mock_type == :freeze
|
|
147
126
|
time - Time.now_without_mock_time
|
|
@@ -155,4 +134,4 @@ class Timecop
|
|
|
155
134
|
Time.respond_to?(:zone) && Time.zone ? Time.zone : Time
|
|
156
135
|
end
|
|
157
136
|
end
|
|
158
|
-
|
|
137
|
+
end
|
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:
|
|
@@ -33,6 +31,7 @@ class Timecop
|
|
|
33
31
|
# 3. Timecop.freeze(date_inst)
|
|
34
32
|
# 4. Timecop.freeze(offset_in_seconds)
|
|
35
33
|
# 5. Timecop.freeze(year, month, day, hour=0, minute=0, second=0)
|
|
34
|
+
# 6. Timecop.freeze() # Defaults to Time.now
|
|
36
35
|
#
|
|
37
36
|
# When a block is also passed, Time.now, DateTime.now and Date.today are all reset to their
|
|
38
37
|
# previous values after the block has finished executing. This allows us to nest multiple
|
|
@@ -104,6 +103,19 @@ class Timecop
|
|
|
104
103
|
instance.instance_variable_get(:@_stack).last
|
|
105
104
|
end
|
|
106
105
|
|
|
106
|
+
def safe_mode=(safe)
|
|
107
|
+
@safe_mode = safe
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def safe_mode?
|
|
111
|
+
@safe_mode ||= false
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Returns whether or not Timecop is currently frozen/travelled
|
|
115
|
+
def frozen?
|
|
116
|
+
!instance.instance_variable_get(:@_stack).empty?
|
|
117
|
+
end
|
|
118
|
+
|
|
107
119
|
private
|
|
108
120
|
def send_travel(mock_type, *args, &block)
|
|
109
121
|
val = instance.send(:travel, mock_type, *args, &block)
|
|
@@ -123,15 +135,18 @@ class Timecop
|
|
|
123
135
|
end
|
|
124
136
|
|
|
125
137
|
def travel(mock_type, *args, &block) #:nodoc:
|
|
138
|
+
raise SafeModeException if Timecop.safe_mode? && !block_given?
|
|
139
|
+
|
|
126
140
|
stack_item = TimeStackItem.new(mock_type, *args)
|
|
127
141
|
|
|
142
|
+
stack_backup = @_stack.dup
|
|
128
143
|
@_stack << stack_item
|
|
129
144
|
|
|
130
145
|
if block_given?
|
|
131
146
|
begin
|
|
132
147
|
yield stack_item.time
|
|
133
148
|
ensure
|
|
134
|
-
@_stack.
|
|
149
|
+
@_stack.replace stack_backup
|
|
135
150
|
end
|
|
136
151
|
end
|
|
137
152
|
end
|
|
@@ -141,6 +156,7 @@ class Timecop
|
|
|
141
156
|
current_baseline = @baseline
|
|
142
157
|
unmock!
|
|
143
158
|
yield
|
|
159
|
+
ensure
|
|
144
160
|
@_stack = current_stack
|
|
145
161
|
@baseline = current_baseline
|
|
146
162
|
end
|
|
@@ -157,4 +173,10 @@ class Timecop
|
|
|
157
173
|
unmock!
|
|
158
174
|
end
|
|
159
175
|
end
|
|
176
|
+
|
|
177
|
+
class SafeModeException < StandardError
|
|
178
|
+
def initialize
|
|
179
|
+
super "Safe mode is enabled, only calls passing a block are allowed."
|
|
180
|
+
end
|
|
181
|
+
end
|
|
160
182
|
end
|
data/lib/timecop/version.rb
CHANGED
data/test/test_helper.rb
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
require 'rubygems'
|
|
2
1
|
require 'bundler/setup'
|
|
3
|
-
require '
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
require 'mocha'
|
|
8
|
-
end
|
|
2
|
+
require 'minitest/autorun'
|
|
3
|
+
require 'minitest/rg'
|
|
4
|
+
|
|
5
|
+
$VERBOSE = true # enable ruby warnings
|
|
9
6
|
|
|
10
|
-
|
|
7
|
+
require 'mocha/setup'
|
|
11
8
|
|
|
9
|
+
class Minitest::Test
|
|
12
10
|
private
|
|
13
11
|
# Tests to see that two times are within the given distance,
|
|
14
12
|
# in seconds, from each other.
|
|
15
13
|
def times_effectively_equal(time1, time2, seconds_interval = 1)
|
|
16
14
|
(time1 - time2).abs <= seconds_interval
|
|
17
15
|
end
|
|
18
|
-
|
|
16
|
+
|
|
19
17
|
def assert_times_effectively_equal(time1, time2, seconds_interval = 1, msg = nil)
|
|
20
18
|
assert times_effectively_equal(time1, time2, seconds_interval), "#{msg}: time1 = #{time1.to_s}, time2 = #{time2.to_s}"
|
|
21
19
|
end
|
|
22
|
-
|
|
20
|
+
|
|
23
21
|
def assert_times_effectively_not_equal(time1, time2, seconds_interval = 1, msg = nil)
|
|
24
22
|
assert !times_effectively_equal(time1, time2, seconds_interval), "#{msg}: time1 = #{time1.to_s}, time2 = #{time2.to_s}"
|
|
25
23
|
end
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
|
|
25
|
+
# Gets the local offset (supplied by ENV['TZ'] or your computer's clock)
|
|
26
|
+
# At the given timestamp, or Time.now if not time is given.
|
|
27
|
+
def local_offset(time = Time.now)
|
|
28
|
+
Time.at(time.to_i).to_datetime.offset
|
|
29
29
|
end
|
|
30
|
-
|
|
31
|
-
TIMEZONES = ["Europe/Paris", "UTC", "
|
|
32
|
-
|
|
30
|
+
|
|
31
|
+
TIMEZONES = ["Europe/Paris", "UTC", "America/Chicago"]
|
|
32
|
+
|
|
33
33
|
def each_timezone
|
|
34
34
|
old_tz = ENV["TZ"]
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
begin
|
|
37
37
|
TIMEZONES.each do |timezone|
|
|
38
38
|
ENV["TZ"] = timezone
|
|
@@ -42,13 +42,13 @@ class Test::Unit::TestCase
|
|
|
42
42
|
ENV["TZ"] = old_tz
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
|
-
|
|
45
|
+
|
|
46
46
|
def a_time_stack_item
|
|
47
47
|
Timecop::TimeStackItem.new(:freeze, 2008, 1, 1, 0, 0, 0)
|
|
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
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
require 'date'
|
|
2
|
-
|
|
3
|
-
require
|
|
2
|
+
require_relative "test_helper"
|
|
3
|
+
require 'timecop'
|
|
4
|
+
require 'active_support/all'
|
|
4
5
|
|
|
5
|
-
class TestTimeStackItem < Test
|
|
6
|
+
class TestTimeStackItem < Minitest::Test
|
|
6
7
|
def teardown
|
|
7
|
-
Timecop.active_support = nil
|
|
8
8
|
Timecop.return
|
|
9
|
+
Time.zone = nil
|
|
9
10
|
end
|
|
10
11
|
|
|
11
12
|
def test_new_with_time
|
|
@@ -85,6 +86,19 @@ class TestTimeStackItem < Test::Unit::TestCase
|
|
|
85
86
|
assert_equal s, stack_item.sec
|
|
86
87
|
end
|
|
87
88
|
|
|
89
|
+
def test_new_with_float
|
|
90
|
+
t = Time.now
|
|
91
|
+
y, m, d, h, min, s = t.year, t.month, t.day, t.hour, t.min, t.sec
|
|
92
|
+
stack_item = Timecop::TimeStackItem.new(:freeze, 0.0)
|
|
93
|
+
|
|
94
|
+
assert_equal y, stack_item.year
|
|
95
|
+
assert_equal m, stack_item.month
|
|
96
|
+
assert_equal d, stack_item.day
|
|
97
|
+
assert_equal h, stack_item.hour
|
|
98
|
+
assert_equal min, stack_item.min
|
|
99
|
+
assert_equal s, stack_item.sec
|
|
100
|
+
end
|
|
101
|
+
|
|
88
102
|
def test_new_with_individual_arguments
|
|
89
103
|
y, m, d, h, min, s = 2008, 10, 10, 10, 10, 10
|
|
90
104
|
stack_item = Timecop::TimeStackItem.new(:freeze, y, m, d, h, min, s)
|
|
@@ -111,49 +125,35 @@ class TestTimeStackItem < Test::Unit::TestCase
|
|
|
111
125
|
assert_equal Rational(1, 24), a_time_stack_item.send(:utc_offset_to_rational, 3600)
|
|
112
126
|
end
|
|
113
127
|
|
|
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
|
|
128
|
+
def test_datetime_in_presence_of_activesupport_timezone
|
|
129
|
+
skip('requires ActiveSupport') unless Time.respond_to? :zone
|
|
130
|
+
backed_up_zone, backed_up_tzvar = Time.zone, ENV['TZ']
|
|
131
131
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
t = DateTime.parse("2009-12-11 00:00:00 -0400")
|
|
132
|
+
Time.zone = ENV['TZ'] = 'America/Los_Angeles'
|
|
133
|
+
t = DateTime.new(2001, 2, 28, 23, 59, 59.5)
|
|
135
134
|
tsi = Timecop::TimeStackItem.new(:freeze, t)
|
|
136
|
-
return if !Time.now.dst? || tsi.time.dst?
|
|
137
135
|
|
|
138
|
-
|
|
136
|
+
assert_date_times_equal t, tsi.datetime
|
|
137
|
+
ensure
|
|
138
|
+
Time.zone, ENV['TZ'] = backed_up_zone, backed_up_tzvar
|
|
139
139
|
end
|
|
140
140
|
|
|
141
|
-
|
|
142
|
-
|
|
141
|
+
# Ensure DateTimes handle changing DST properly
|
|
142
|
+
def test_datetime_for_dst_to_non_dst
|
|
143
|
+
Timecop.freeze(DateTime.parse("2009-12-1 00:38:00 -0500"))
|
|
143
144
|
t = DateTime.parse("2009-10-11 00:00:00 -0400")
|
|
144
145
|
tsi = Timecop::TimeStackItem.new(:freeze, t)
|
|
145
|
-
return if Time.now.dst? || !tsi.time.dst?
|
|
146
146
|
|
|
147
|
-
|
|
147
|
+
assert_date_times_equal t, tsi.datetime
|
|
148
148
|
end
|
|
149
149
|
|
|
150
|
-
# Ensure DateTimes handle changing DST properly
|
|
151
|
-
def
|
|
150
|
+
# Ensure DateTimes handle changing DST properly when changing from DateTime to Time
|
|
151
|
+
def test_datetime_for_dst_to_time_for_non_dst
|
|
152
152
|
Timecop.freeze(DateTime.parse("2009-12-1 00:38:00 -0500"))
|
|
153
153
|
t = DateTime.parse("2009-10-11 00:00:00 -0400")
|
|
154
154
|
tsi = Timecop::TimeStackItem.new(:freeze, t)
|
|
155
155
|
|
|
156
|
-
assert_date_times_equal t, tsi.
|
|
156
|
+
assert_date_times_equal t.to_time, tsi.time
|
|
157
157
|
end
|
|
158
158
|
|
|
159
159
|
def test_datetime_for_non_dst_to_dst
|
|
@@ -184,7 +184,6 @@ class TestTimeStackItem < Test::Unit::TestCase
|
|
|
184
184
|
end
|
|
185
185
|
|
|
186
186
|
def test_timezones
|
|
187
|
-
require 'active_support/all'
|
|
188
187
|
Time.zone = "Europe/Zurich"
|
|
189
188
|
time = Time.zone.parse("2012-12-27T12:12:12+08:00")
|
|
190
189
|
Timecop.freeze(time) do |frozen_time|
|
|
@@ -193,12 +192,11 @@ class TestTimeStackItem < Test::Unit::TestCase
|
|
|
193
192
|
end
|
|
194
193
|
|
|
195
194
|
def test_timezones_apply_dates
|
|
196
|
-
|
|
197
|
-
Time.zone = "Marshall Is."
|
|
195
|
+
Time.zone = "Central Time (US & Canada)"
|
|
198
196
|
time = Time.zone.local(2013,1,3)
|
|
199
197
|
|
|
200
198
|
Timecop.freeze(time) do
|
|
201
|
-
assert_equal time.to_date,
|
|
199
|
+
assert_equal time.to_date, Time.now.to_date
|
|
202
200
|
end
|
|
203
201
|
end
|
|
204
202
|
|
|
@@ -212,48 +210,18 @@ class TestTimeStackItem < Test::Unit::TestCase
|
|
|
212
210
|
assert_equal tsi.send(:scaling_factor), 4, "Scaling factor not set"
|
|
213
211
|
end
|
|
214
212
|
|
|
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
213
|
def test_parse_only_string_with_active_support
|
|
222
214
|
Time.expects(:parse).never
|
|
223
215
|
Timecop.freeze(2011, 01, 02, hour=0, minute=0, second=0)
|
|
224
216
|
end
|
|
225
217
|
|
|
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
218
|
def test_parse_date
|
|
246
|
-
|
|
247
|
-
Timecop.freeze(Date.new(2012, 6, 9))
|
|
248
|
-
end
|
|
219
|
+
Timecop.freeze(Date.new(2012, 6, 9))
|
|
249
220
|
end
|
|
250
221
|
|
|
251
222
|
def test_time_zone_returns_nil
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
assert_nothing_raised do
|
|
255
|
-
Timecop.freeze
|
|
256
|
-
end
|
|
223
|
+
Time.zone = nil
|
|
224
|
+
Timecop.freeze
|
|
257
225
|
end
|
|
258
226
|
|
|
259
227
|
def test_nsecs_are_set
|
|
@@ -263,13 +231,59 @@ class TestTimeStackItem < Test::Unit::TestCase
|
|
|
263
231
|
assert_equal time.nsec, Time.now.nsec if (Time.now.respond_to?(:nsec))
|
|
264
232
|
end
|
|
265
233
|
|
|
266
|
-
def
|
|
267
|
-
|
|
234
|
+
def test_time_with_different_timezone_keeps_nsec
|
|
235
|
+
Time.zone = "Tokyo"
|
|
236
|
+
t = Time.now
|
|
237
|
+
Timecop.freeze(t) do
|
|
238
|
+
assert_equal t, Time.now
|
|
239
|
+
assert_equal t.nsec, Time.now.nsec if (Time.now.respond_to?(:nsec))
|
|
240
|
+
end
|
|
241
|
+
end
|
|
268
242
|
|
|
243
|
+
def test_time_now_always_returns_local_time
|
|
244
|
+
Time.zone = "Tokyo"
|
|
245
|
+
t = Time.utc(2000, 1, 1)
|
|
246
|
+
Timecop.freeze(t) do
|
|
247
|
+
assert_equal t.getlocal.zone, Time.now.zone
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
def test_time_zone_now_returns_time_in_that_zone
|
|
252
|
+
Time.zone = "Hawaii"
|
|
253
|
+
t = Time.utc(2000, 1, 1)
|
|
254
|
+
Timecop.freeze(t) do
|
|
255
|
+
assert_equal t, Time.zone.now
|
|
256
|
+
assert_equal 'HST', Time.zone.now.zone
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
def test_freezing_a_time_leaves_timezone_intact
|
|
269
261
|
Time.zone = "Tokyo"
|
|
270
262
|
t = Time.now
|
|
263
|
+
t_dup = t.dup
|
|
264
|
+
Timecop.freeze(t) {}
|
|
265
|
+
assert_equal t_dup.zone, t.zone
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
def test_freezing_a_time_with_zone_returns_proper_zones
|
|
269
|
+
Time.zone = "Hawaii"
|
|
270
|
+
t = ActiveSupport::TimeWithZone.new(Time.utc(2000, 1, 1), ActiveSupport::TimeZone['Tokyo'])
|
|
271
271
|
Timecop.freeze(t) do
|
|
272
|
-
|
|
272
|
+
local_now = Time.now
|
|
273
|
+
assert_equal t, local_now
|
|
274
|
+
assert_equal t.getlocal.zone, local_now.zone
|
|
275
|
+
|
|
276
|
+
zoned_now = Time.zone.now
|
|
277
|
+
assert_equal t, zoned_now
|
|
278
|
+
assert_equal 'HST', zoned_now.zone
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
def test_datetime_timezones
|
|
283
|
+
dt = DateTime.new(2011,1,3,15,25,0,"-6")
|
|
284
|
+
Timecop.freeze(dt) do
|
|
285
|
+
now = DateTime.now
|
|
286
|
+
assert_equal dt, now, "#{dt.to_f}, #{now.to_f}"
|
|
273
287
|
end
|
|
274
288
|
end
|
|
275
289
|
end
|
data/test/timecop_test.rb
CHANGED
|
@@ -1,23 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
require
|
|
3
|
-
require File.join(File.dirname(__FILE__), '..', 'lib', 'timecop')
|
|
1
|
+
require_relative "test_helper"
|
|
2
|
+
require 'timecop'
|
|
4
3
|
|
|
5
|
-
class TestTimecop < Test
|
|
4
|
+
class TestTimecop < Minitest::Test
|
|
6
5
|
def teardown
|
|
7
6
|
Timecop.return
|
|
8
7
|
end
|
|
9
8
|
|
|
10
9
|
def test_freeze_changes_and_resets_time
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
Timecop.freeze(
|
|
17
|
-
|
|
10
|
+
outer_freeze_time = Time.local(2001, 01, 01)
|
|
11
|
+
inner_freeze_block = Time.local(2002, 02, 02)
|
|
12
|
+
inner_freeze_one = Time.local(2003, 03, 03)
|
|
13
|
+
inner_freeze_two = Time.local(2004, 04, 04)
|
|
14
|
+
|
|
15
|
+
Timecop.freeze(outer_freeze_time) do
|
|
16
|
+
assert_times_effectively_equal outer_freeze_time, Time.now
|
|
17
|
+
Timecop.freeze(inner_freeze_block) do
|
|
18
|
+
assert_times_effectively_equal inner_freeze_block, Time.now
|
|
19
|
+
Timecop.freeze(inner_freeze_one)
|
|
20
|
+
assert_times_effectively_equal inner_freeze_one, Time.now
|
|
21
|
+
Timecop.freeze(inner_freeze_two)
|
|
22
|
+
assert_times_effectively_equal inner_freeze_two, Time.now
|
|
23
|
+
end
|
|
24
|
+
assert_times_effectively_equal outer_freeze_time, Time.now
|
|
18
25
|
end
|
|
19
|
-
|
|
20
|
-
assert_not_equal t, Time.now
|
|
21
26
|
end
|
|
22
27
|
|
|
23
28
|
def test_freeze_yields_mocked_time
|
|
@@ -25,7 +30,7 @@ class TestTimecop < Test::Unit::TestCase
|
|
|
25
30
|
assert_equal frozen_time, Time.now
|
|
26
31
|
end
|
|
27
32
|
end
|
|
28
|
-
|
|
33
|
+
|
|
29
34
|
def test_freeze_then_return_unsets_mock_time
|
|
30
35
|
Timecop.freeze(1)
|
|
31
36
|
Timecop.return
|
|
@@ -53,8 +58,11 @@ class TestTimecop < Test::Unit::TestCase
|
|
|
53
58
|
def test_travel_does_not_reduce_precision_of_datetime
|
|
54
59
|
# requires to_r on Float (>= 1.9)
|
|
55
60
|
if Float.method_defined?(:to_r)
|
|
56
|
-
Timecop.travel(1)
|
|
57
|
-
|
|
61
|
+
Timecop.travel(Time.new(2014, 1, 1, 0, 0, 0))
|
|
62
|
+
assert DateTime.now != DateTime.now
|
|
63
|
+
|
|
64
|
+
Timecop.travel(Time.new(2014, 1, 1, 0, 0, 59))
|
|
65
|
+
assert DateTime.now != DateTime.now
|
|
58
66
|
end
|
|
59
67
|
end
|
|
60
68
|
|
|
@@ -107,7 +115,7 @@ class TestTimecop < Test::Unit::TestCase
|
|
|
107
115
|
end
|
|
108
116
|
assert_equal t, Time.now
|
|
109
117
|
end
|
|
110
|
-
|
|
118
|
+
assert t != Time.now
|
|
111
119
|
end
|
|
112
120
|
|
|
113
121
|
def test_freeze_with_time_instance_works_as_expected
|
|
@@ -118,9 +126,9 @@ class TestTimecop < Test::Unit::TestCase
|
|
|
118
126
|
assert_equal Date.new(2008, 10, 10), Date.today
|
|
119
127
|
end
|
|
120
128
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
129
|
+
assert t != Time.now
|
|
130
|
+
assert DateTime.new(2008, 10, 10, 10, 10, 10, local_offset) != DateTime.now
|
|
131
|
+
assert Date.new(2008, 10, 10) != Date.today
|
|
124
132
|
end
|
|
125
133
|
|
|
126
134
|
def test_freeze_with_datetime_on_specific_timezone_during_dst
|
|
@@ -179,9 +187,9 @@ class TestTimecop < Test::Unit::TestCase
|
|
|
179
187
|
assert_equal Time.local(2008, 10, 10, 0, 0, 0), Time.now
|
|
180
188
|
assert_date_times_equal DateTime.new(2008, 10, 10, 0, 0, 0, local_offset), DateTime.now
|
|
181
189
|
end
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
190
|
+
assert d != Date.today
|
|
191
|
+
assert Time.local(2008, 10, 10, 0, 0, 0) != Time.now
|
|
192
|
+
assert DateTime.new(2008, 10, 10, 0, 0, 0, local_offset) != DateTime.now
|
|
185
193
|
end
|
|
186
194
|
|
|
187
195
|
def test_freeze_with_integer_instance_works_as_expected
|
|
@@ -196,9 +204,9 @@ class TestTimecop < Test::Unit::TestCase
|
|
|
196
204
|
assert_equal Date.new(2008, 10, 10), Date.today
|
|
197
205
|
end
|
|
198
206
|
end
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
207
|
+
assert t != Time.now
|
|
208
|
+
assert DateTime.new(2008, 10, 10, 10, 10, 10) != DateTime.now
|
|
209
|
+
assert Date.new(2008, 10, 10) != Date.today
|
|
202
210
|
end
|
|
203
211
|
|
|
204
212
|
def test_exception_thrown_in_freeze_block_properly_resets_time
|
|
@@ -209,11 +217,19 @@ class TestTimecop < Test::Unit::TestCase
|
|
|
209
217
|
raise "blah exception"
|
|
210
218
|
end
|
|
211
219
|
rescue
|
|
212
|
-
|
|
220
|
+
assert t != Time.now
|
|
213
221
|
assert_nil Time.send(:mock_time)
|
|
214
222
|
end
|
|
215
223
|
end
|
|
216
224
|
|
|
225
|
+
def test_exception_thrown_in_return_block_restores_previous_time
|
|
226
|
+
t = Time.local(2008, 10, 10, 10, 10, 10)
|
|
227
|
+
Timecop.freeze(t) do
|
|
228
|
+
Timecop.return { raise 'foobar' } rescue nil
|
|
229
|
+
assert_equal t, Time.now
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
217
233
|
def test_freeze_freezes_time
|
|
218
234
|
t = Time.local(2008, 10, 10, 10, 10, 10)
|
|
219
235
|
now = Time.now
|
|
@@ -243,6 +259,11 @@ class TestTimecop < Test::Unit::TestCase
|
|
|
243
259
|
each_timezone do
|
|
244
260
|
t = DateTime.parse("2009-10-11 00:38:00 +0200")
|
|
245
261
|
Timecop.freeze(t) do
|
|
262
|
+
if ENV['TZ'] == 'UTC'
|
|
263
|
+
assert_equal(local_offset, 0, "Local offset not be zero for #{ENV['TZ']}")
|
|
264
|
+
else
|
|
265
|
+
assert(local_offset, 0 != "Local offset should not be zero for #{ENV['TZ']}")
|
|
266
|
+
end
|
|
246
267
|
assert_equal local_offset, DateTime.now.offset, "Failed for timezone: #{ENV['TZ']}"
|
|
247
268
|
end
|
|
248
269
|
end
|
|
@@ -273,6 +294,19 @@ class TestTimecop < Test::Unit::TestCase
|
|
|
273
294
|
end
|
|
274
295
|
end
|
|
275
296
|
|
|
297
|
+
def test_freeze_without_arguments_instance_works_as_expected
|
|
298
|
+
t = Time.local(2008, 10, 10, 10, 10, 10)
|
|
299
|
+
Timecop.freeze(t) do
|
|
300
|
+
assert_equal t, Time.now
|
|
301
|
+
Timecop.freeze do
|
|
302
|
+
assert_equal t, Time.now
|
|
303
|
+
assert_equal Time.local(2008, 10, 10, 10, 10, 10), Time.now
|
|
304
|
+
assert_equal Date.new(2008, 10, 10), Date.today
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
assert t != Time.now
|
|
308
|
+
end
|
|
309
|
+
|
|
276
310
|
def test_destructive_methods_on_frozen_time
|
|
277
311
|
# Use any time zone other than UTC.
|
|
278
312
|
ENV['TZ'] = 'EST'
|
|
@@ -303,13 +337,13 @@ class TestTimecop < Test::Unit::TestCase
|
|
|
303
337
|
end
|
|
304
338
|
|
|
305
339
|
def test_recursive_travel_yields_correct_time
|
|
306
|
-
Timecop.travel(2008, 10, 10, 10, 10, 10) do
|
|
340
|
+
Timecop.travel(2008, 10, 10, 10, 10, 10) do
|
|
307
341
|
Timecop.travel(2008, 9, 9, 9, 9, 9) do |inner_freeze|
|
|
308
342
|
assert_times_effectively_equal inner_freeze, Time.now, 1, "Failed to yield current time back to block"
|
|
309
343
|
end
|
|
310
344
|
end
|
|
311
345
|
end
|
|
312
|
-
|
|
346
|
+
|
|
313
347
|
def test_recursive_travel_then_freeze
|
|
314
348
|
t = Time.local(2008, 10, 10, 10, 10, 10)
|
|
315
349
|
Timecop.travel(2008, 10, 10, 10, 10, 10) do
|
|
@@ -431,8 +465,84 @@ class TestTimecop < Test::Unit::TestCase
|
|
|
431
465
|
end
|
|
432
466
|
|
|
433
467
|
def test_not_callable_send_travel
|
|
434
|
-
|
|
468
|
+
assert_raises NoMethodError do
|
|
435
469
|
Timecop.send_travel(:travel, Time.now - 100)
|
|
436
470
|
end
|
|
437
471
|
end
|
|
472
|
+
|
|
473
|
+
def test_datetime_to_time_for_dst_to_non_dst
|
|
474
|
+
# Start at a time subject to DST
|
|
475
|
+
Timecop.travel(2009, 4, 1, 0, 0, 0, -4*60*60) do
|
|
476
|
+
|
|
477
|
+
# Then freeze, via DateTime, at a time not subject to DST
|
|
478
|
+
t = DateTime.new(2009,01,01,0,0,0, "-0500")
|
|
479
|
+
Timecop.freeze(t) do
|
|
480
|
+
|
|
481
|
+
# Check the current time via DateTime.now--should be what we asked for
|
|
482
|
+
assert_date_times_equal t, DateTime.now
|
|
483
|
+
|
|
484
|
+
# Then check the current time via Time.now (not DateTime.now)
|
|
485
|
+
assert_times_effectively_equal Time.new(2009, 1, 1, 0, 0, 0, -5*60*60), Time.now
|
|
486
|
+
end
|
|
487
|
+
end
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
def test_raises_when_safe_mode_and_no_block
|
|
491
|
+
with_safe_mode do
|
|
492
|
+
assert_raises Timecop::SafeModeException do
|
|
493
|
+
Timecop.freeze
|
|
494
|
+
end
|
|
495
|
+
end
|
|
496
|
+
end
|
|
497
|
+
|
|
498
|
+
def test_no_raise_when_safe_mode_and_block_used
|
|
499
|
+
with_safe_mode do
|
|
500
|
+
Timecop.freeze {}
|
|
501
|
+
end
|
|
502
|
+
end
|
|
503
|
+
|
|
504
|
+
def test_no_raise_when_not_safe_mode_and_no_block
|
|
505
|
+
with_safe_mode(false) do
|
|
506
|
+
Timecop.freeze
|
|
507
|
+
end
|
|
508
|
+
end
|
|
509
|
+
|
|
510
|
+
def test_date_strptime_without_year
|
|
511
|
+
Timecop.freeze(Time.new(1984,2,28)) do
|
|
512
|
+
assert_equal Date.strptime('04-14', '%m-%d'), Date.new(1984, 4, 14)
|
|
513
|
+
end
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
def test_date_strptime_without_specifying_format
|
|
517
|
+
Timecop.freeze(Time.new(1984,2,28)) do
|
|
518
|
+
assert_equal Date.strptime('1999-04-14'), Date.new(1999, 4, 14)
|
|
519
|
+
end
|
|
520
|
+
end
|
|
521
|
+
|
|
522
|
+
def test_frozen_after_freeze
|
|
523
|
+
Timecop.freeze
|
|
524
|
+
assert Timecop.frozen?
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
def test_frozen_inside_freeze
|
|
528
|
+
Timecop.freeze do
|
|
529
|
+
assert Timecop.frozen?
|
|
530
|
+
end
|
|
531
|
+
end
|
|
532
|
+
|
|
533
|
+
def test_not_frozen_after_return
|
|
534
|
+
Timecop.freeze
|
|
535
|
+
Timecop.return
|
|
536
|
+
assert !Timecop.frozen?
|
|
537
|
+
end
|
|
538
|
+
|
|
539
|
+
private
|
|
540
|
+
|
|
541
|
+
def with_safe_mode(enabled=true)
|
|
542
|
+
mode = Timecop.safe_mode?
|
|
543
|
+
Timecop.safe_mode = enabled
|
|
544
|
+
yield
|
|
545
|
+
ensure
|
|
546
|
+
Timecop.safe_mode = mode
|
|
547
|
+
end
|
|
438
548
|
end
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
class TestTimecopWithoutDateButWithTime < Test::Unit::TestCase
|
|
4
|
-
TIMECOP_LIB = File.join(File.dirname(__FILE__), '..', 'lib', 'timecop')
|
|
1
|
+
require_relative "test_helper"
|
|
2
|
+
require "time"
|
|
5
3
|
|
|
4
|
+
class TestTimecopWithoutDateButWithTime < Minitest::Test
|
|
6
5
|
def test_loads_properly_when_time_is_required_instead_of_date
|
|
7
|
-
|
|
8
|
-
require "time"
|
|
9
|
-
require TIMECOP_LIB
|
|
10
|
-
end
|
|
6
|
+
require 'timecop'
|
|
11
7
|
end
|
|
12
8
|
end
|
|
@@ -1,34 +1,33 @@
|
|
|
1
|
+
require_relative "test_helper"
|
|
2
|
+
require 'timecop'
|
|
1
3
|
|
|
2
|
-
|
|
3
|
-
require File.join(File.dirname(__FILE__), '..', 'lib', 'timecop')
|
|
4
|
+
class TestTimecopWithoutDate < Minitest::Test
|
|
4
5
|
|
|
5
|
-
class TestTimecopWithoutDate < Test::Unit::TestCase
|
|
6
|
-
|
|
7
6
|
def setup
|
|
8
7
|
Object.send(:remove_const, :Date) if Object.const_defined?(:Date)
|
|
9
8
|
Object.send(:remove_const, :DateTime) if Object.const_defined?(:DateTime)
|
|
10
9
|
end
|
|
11
|
-
|
|
10
|
+
|
|
12
11
|
# just in case...let's really make sure that Timecop is disabled between tests...
|
|
13
12
|
def teardown
|
|
14
13
|
Timecop.return
|
|
15
14
|
end
|
|
16
|
-
|
|
15
|
+
|
|
17
16
|
def test_freeze_changes_and_resets_time
|
|
18
17
|
# depending on how we're invoked (individually or via the rake test suite)
|
|
19
18
|
assert !Time.respond_to?(:zone) || Time.zone.nil?
|
|
20
|
-
|
|
19
|
+
|
|
21
20
|
t = Time.local(2008, 10, 10, 10, 10, 10)
|
|
22
|
-
|
|
21
|
+
assert t != Time.now
|
|
23
22
|
Timecop.freeze(2008, 10, 10, 10, 10, 10) do
|
|
24
23
|
assert_equal t, Time.now
|
|
25
24
|
end
|
|
26
|
-
|
|
25
|
+
assert t != Time.now
|
|
27
26
|
end
|
|
28
|
-
|
|
27
|
+
|
|
29
28
|
def test_recursive_freeze
|
|
30
29
|
t = Time.local(2008, 10, 10, 10, 10, 10)
|
|
31
|
-
Timecop.freeze(2008, 10, 10, 10, 10, 10) do
|
|
30
|
+
Timecop.freeze(2008, 10, 10, 10, 10, 10) do
|
|
32
31
|
assert_equal t, Time.now
|
|
33
32
|
t2 = Time.local(2008, 9, 9, 9, 9, 9)
|
|
34
33
|
Timecop.freeze(2008, 9, 9, 9, 9, 9) do
|
|
@@ -38,7 +37,7 @@ class TestTimecopWithoutDate < Test::Unit::TestCase
|
|
|
38
37
|
end
|
|
39
38
|
assert_nil Time.send(:mock_time)
|
|
40
39
|
end
|
|
41
|
-
|
|
40
|
+
|
|
42
41
|
def test_exception_thrown_in_freeze_block_properly_resets_time
|
|
43
42
|
t = Time.local(2008, 10, 10, 10, 10, 10)
|
|
44
43
|
begin
|
|
@@ -47,11 +46,11 @@ class TestTimecopWithoutDate < Test::Unit::TestCase
|
|
|
47
46
|
raise "blah exception"
|
|
48
47
|
end
|
|
49
48
|
rescue
|
|
50
|
-
|
|
49
|
+
assert t != Time.now
|
|
51
50
|
assert_nil Time.send(:mock_time)
|
|
52
51
|
end
|
|
53
52
|
end
|
|
54
|
-
|
|
53
|
+
|
|
55
54
|
def test_freeze_freezes_time
|
|
56
55
|
t = Time.local(2008, 10, 10, 10, 10, 10)
|
|
57
56
|
now = Time.now
|
|
@@ -63,7 +62,7 @@ class TestTimecopWithoutDate < Test::Unit::TestCase
|
|
|
63
62
|
assert_equal new_t, Time.now
|
|
64
63
|
end
|
|
65
64
|
end
|
|
66
|
-
|
|
65
|
+
|
|
67
66
|
def test_travel_keeps_time_moving
|
|
68
67
|
t = Time.local(2008, 10, 10, 10, 10, 10)
|
|
69
68
|
now = Time.now
|
|
@@ -74,10 +73,10 @@ class TestTimecopWithoutDate < Test::Unit::TestCase
|
|
|
74
73
|
assert_times_effectively_not_equal new_now, Time.now, 0.25, "Looks like time is not moving"
|
|
75
74
|
end
|
|
76
75
|
end
|
|
77
|
-
|
|
76
|
+
|
|
78
77
|
def test_recursive_travel_maintains_each_context
|
|
79
78
|
t = Time.local(2008, 10, 10, 10, 10, 10)
|
|
80
|
-
Timecop.travel(2008, 10, 10, 10, 10, 10) do
|
|
79
|
+
Timecop.travel(2008, 10, 10, 10, 10, 10) do
|
|
81
80
|
assert((t - Time.now).abs < 50, "Failed to travel time.")
|
|
82
81
|
t2 = Time.local(2008, 9, 9, 9, 9, 9)
|
|
83
82
|
Timecop.travel(2008, 9, 9, 9, 9, 9) do
|
|
@@ -88,10 +87,10 @@ class TestTimecopWithoutDate < Test::Unit::TestCase
|
|
|
88
87
|
end
|
|
89
88
|
assert_nil Time.send(:mock_time)
|
|
90
89
|
end
|
|
91
|
-
|
|
90
|
+
|
|
92
91
|
def test_recursive_travel_then_freeze
|
|
93
92
|
t = Time.local(2008, 10, 10, 10, 10, 10)
|
|
94
|
-
Timecop.travel(2008, 10, 10, 10, 10, 10) do
|
|
93
|
+
Timecop.travel(2008, 10, 10, 10, 10, 10) do
|
|
95
94
|
assert((t - Time.now).abs < 50, "Failed to travel time.")
|
|
96
95
|
t2 = Time.local(2008, 9, 9, 9, 9, 9)
|
|
97
96
|
Timecop.freeze(2008, 9, 9, 9, 9, 9) do
|
|
@@ -101,10 +100,10 @@ class TestTimecopWithoutDate < Test::Unit::TestCase
|
|
|
101
100
|
end
|
|
102
101
|
assert_nil Time.send(:mock_time)
|
|
103
102
|
end
|
|
104
|
-
|
|
103
|
+
|
|
105
104
|
def test_recursive_freeze_then_travel
|
|
106
105
|
t = Time.local(2008, 10, 10, 10, 10, 10)
|
|
107
|
-
Timecop.freeze(t) do
|
|
106
|
+
Timecop.freeze(t) do
|
|
108
107
|
assert_equal t, Time.now
|
|
109
108
|
t2 = Time.local(2008, 9, 9, 9, 9, 9)
|
|
110
109
|
Timecop.travel(t2) do
|
|
@@ -113,7 +112,7 @@ class TestTimecopWithoutDate < Test::Unit::TestCase
|
|
|
113
112
|
end
|
|
114
113
|
assert_equal t, Time.now
|
|
115
114
|
end
|
|
116
|
-
assert_nil Time.send(:mock_time)
|
|
115
|
+
assert_nil Time.send(:mock_time)
|
|
117
116
|
end
|
|
118
117
|
|
|
119
118
|
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.
|
|
5
|
-
prerelease:
|
|
4
|
+
version: 0.8.1
|
|
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:
|
|
12
|
+
date: 2016-04-01 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
|
|
@@ -28,37 +27,35 @@ files:
|
|
|
28
27
|
- lib/timecop.rb
|
|
29
28
|
- lib/timecop/time_extensions.rb
|
|
30
29
|
- lib/timecop/time_stack_item.rb
|
|
31
|
-
- lib/timecop/version.rb
|
|
32
30
|
- lib/timecop/timecop.rb
|
|
33
|
-
-
|
|
31
|
+
- lib/timecop/version.rb
|
|
34
32
|
- test/test_helper.rb
|
|
35
33
|
- test/time_stack_item_test.rb
|
|
36
34
|
- test/timecop_test.rb
|
|
37
|
-
- test/timecop_without_date_test.rb
|
|
38
35
|
- test/timecop_without_date_but_with_time_test.rb
|
|
36
|
+
- test/timecop_without_date_test.rb
|
|
39
37
|
homepage: https://github.com/travisjeffery/timecop
|
|
40
38
|
licenses:
|
|
41
39
|
- MIT
|
|
40
|
+
metadata: {}
|
|
42
41
|
post_install_message:
|
|
43
42
|
rdoc_options:
|
|
44
|
-
- --charset=UTF-8
|
|
43
|
+
- "--charset=UTF-8"
|
|
45
44
|
require_paths:
|
|
46
45
|
- lib
|
|
47
46
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
48
|
-
none: false
|
|
49
47
|
requirements:
|
|
50
|
-
- -
|
|
48
|
+
- - ">="
|
|
51
49
|
- !ruby/object:Gem::Version
|
|
52
|
-
version:
|
|
50
|
+
version: 1.9.2
|
|
53
51
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
54
|
-
none: false
|
|
55
52
|
requirements:
|
|
56
|
-
- -
|
|
53
|
+
- - ">="
|
|
57
54
|
- !ruby/object:Gem::Version
|
|
58
55
|
version: '0'
|
|
59
56
|
requirements: []
|
|
60
57
|
rubyforge_project: timecop
|
|
61
|
-
rubygems_version:
|
|
58
|
+
rubygems_version: 2.4.5
|
|
62
59
|
signing_key:
|
|
63
60
|
specification_version: 3
|
|
64
61
|
summary: A gem providing "time travel" and "time freezing" capabilities, making it
|
|
@@ -70,3 +67,4 @@ test_files:
|
|
|
70
67
|
- test/timecop_test.rb
|
|
71
68
|
- test/timecop_without_date_test.rb
|
|
72
69
|
- test/timecop_without_date_but_with_time_test.rb
|
|
70
|
+
has_rdoc:
|