timecop 0.3.1 → 0.3.4.rc1
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/History.txt +12 -1
- data/README.rdoc +7 -9
- data/Rakefile +2 -1
- data/VERSION.yml +3 -2
- data/lib/timecop/time_extensions.rb +5 -18
- data/lib/timecop/time_stack_item.rb +77 -0
- data/lib/timecop/timecop.rb +4 -38
- data/test/run_tests.sh +5 -2
- data/test/test_time_stack_item.rb +93 -0
- data/test/test_timecop.rb +70 -13
- data/test/test_timecop_without_date.rb +1 -1
- data/test/test_timecop_without_date_but_with_time.rb +12 -0
- metadata +9 -7
- data/lib/timecop/stack_item.rb +0 -12
- data/test/test_timecop_internals.rb +0 -69
data/History.txt
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
=== 0.3.2 / 2009-10-24
|
2
|
+
|
3
|
+
* Maintenance
|
4
|
+
* Fix various timezone-related issues. Notably, when traveling to a DateTime
|
5
|
+
instance specified in a non-local timezone, convert provided DateTime
|
6
|
+
instance to a local instance and return that from DateTime.now.
|
7
|
+
Code contributed by Michaël Witrant [piglop]
|
8
|
+
* Fix bug that would not allow Timecop to be used when Ruby's 'date'
|
9
|
+
library had not been previously loaded.
|
10
|
+
Code contributed by Tuomas Kareinen [tuomas]
|
11
|
+
|
1
12
|
=== 0.3.1 / 2009-09-30
|
2
13
|
|
3
14
|
* Maintenance
|
@@ -7,7 +18,7 @@
|
|
7
18
|
|
8
19
|
* API
|
9
20
|
* Completely remove Timecop#unset_all (deprecated by Timecop#return in 0.2.0)
|
10
|
-
* Return Time.now from #freeze, #travel and #return -- code contributed by Keith Bennett
|
21
|
+
* Return Time.now from #freeze, #travel and #return -- code contributed by Keith Bennett [keithrbennett]
|
11
22
|
|
12
23
|
* Maintenance
|
13
24
|
* Fix bug that left Time#mock_time set in some instances
|
data/README.rdoc
CHANGED
@@ -6,10 +6,15 @@
|
|
6
6
|
|
7
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.
|
8
8
|
|
9
|
+
== INSTALL
|
10
|
+
|
11
|
+
gem install timecop
|
12
|
+
|
9
13
|
== FEATURES
|
10
14
|
|
11
15
|
* Freeze time to a specific point.
|
12
16
|
* Travel back to a specific point in time, but allow time to continue moving forward from there.
|
17
|
+
* No dependencies, can be used with _any_ ruby project
|
13
18
|
* Timecop api allows arguments to be passed into #freeze and #travel as one of the following:
|
14
19
|
* Time instance
|
15
20
|
* DateTime instance
|
@@ -54,16 +59,9 @@ in config/environments/test.rb
|
|
54
59
|
sleep(10)
|
55
60
|
new_time == Time.now # ==> false
|
56
61
|
|
57
|
-
== DEPENDENCIES
|
58
|
-
|
59
|
-
* None
|
60
|
-
|
61
|
-
== INSTALL
|
62
|
-
|
63
|
-
* sudo gem install timecop (latest stable version from rubyforge)
|
64
|
-
* sudo gem install jtrupiano-timecop (HEAD of the repo from github)
|
65
|
-
|
66
62
|
== REFERENCES
|
67
63
|
|
64
|
+
* "0.3.2 release":http://blog.smartlogicsolutions.com/2009/10/24/timecop-0-3-2-released/
|
65
|
+
* "0.3.0 release":http://blog.smartlogicsolutions.com/2009/09/20/timecop-0-3-0-released/
|
68
66
|
* "0.2.0 release":http://blog.smartlogicsolutions.com/2008/12/24/timecop-2-released-freeze-and-rebase-time-ruby/
|
69
67
|
* "0.1.0 release":http://blog.smartlogicsolutions.com/2008/11/19/timecop-freeze-time-in-ruby-for-better-testing/
|
data/Rakefile
CHANGED
@@ -2,7 +2,7 @@ require 'rake'
|
|
2
2
|
require 'rake/testtask'
|
3
3
|
require 'rake/rdoctask'
|
4
4
|
|
5
|
-
gem 'jeweler', '~> 1.
|
5
|
+
gem 'jeweler', '~> 1.3.0'
|
6
6
|
|
7
7
|
begin
|
8
8
|
require 'jeweler'
|
@@ -16,6 +16,7 @@ begin
|
|
16
16
|
s.authors = ["John Trupiano"]
|
17
17
|
s.files = FileList["[A-Z]*", "{bin,lib,test}/**/*"]
|
18
18
|
end
|
19
|
+
Jeweler::GemcutterTasks.new
|
19
20
|
Jeweler::RubyforgeTasks.new do |rubyforge|
|
20
21
|
rubyforge.doc_task = "rdoc"
|
21
22
|
rubyforge.remote_doc_path = "timecop"
|
data/VERSION.yml
CHANGED
@@ -7,12 +7,11 @@
|
|
7
7
|
|
8
8
|
class Time #:nodoc:
|
9
9
|
class << self
|
10
|
-
# Time we might be behaving as
|
11
|
-
#attr_reader :mock_time
|
12
10
|
|
13
11
|
@@mock_offset = nil
|
14
12
|
@@mock_time = nil
|
15
13
|
|
14
|
+
# Time we are behaving as
|
16
15
|
def mock_time
|
17
16
|
if !@@mock_offset.nil?
|
18
17
|
now_without_mock_time - @@mock_offset
|
@@ -50,21 +49,15 @@ class Time #:nodoc:
|
|
50
49
|
end
|
51
50
|
end
|
52
51
|
|
53
|
-
if Object.const_defined?(:Date)
|
52
|
+
if Object.const_defined?(:Date) && Date.respond_to?(:today)
|
54
53
|
class Date #:nodoc:
|
55
54
|
class << self
|
56
|
-
def mock_date
|
57
|
-
now = Time.mock_time
|
58
|
-
return nil if now.nil?
|
59
|
-
Date.new(now.year, now.month, now.day)
|
60
|
-
end
|
61
|
-
|
62
55
|
# Alias the original today
|
63
56
|
alias_method :today_without_mock_date, :today
|
64
57
|
|
65
58
|
# Define today_with_mock_date
|
66
59
|
def today_with_mock_date
|
67
|
-
|
60
|
+
Time.now.send(:to_date)
|
68
61
|
end
|
69
62
|
|
70
63
|
# Alias today to today_with_mock_date
|
@@ -73,21 +66,15 @@ if Object.const_defined?(:Date)
|
|
73
66
|
end
|
74
67
|
end
|
75
68
|
|
76
|
-
if Object.const_defined?(:DateTime)
|
69
|
+
if Object.const_defined?(:DateTime) && DateTime.respond_to?(:now)
|
77
70
|
class DateTime #:nodoc:
|
78
71
|
class << self
|
79
|
-
def mock_time
|
80
|
-
t_now = Time.mock_time
|
81
|
-
return nil if t_now.nil?
|
82
|
-
DateTime.new(t_now.year, t_now.month, t_now.day, t_now.hour, t_now.min, t_now.sec)
|
83
|
-
end
|
84
|
-
|
85
72
|
# Alias the original now
|
86
73
|
alias_method :now_without_mock_time, :now
|
87
74
|
|
88
75
|
# Define now_with_mock_time
|
89
76
|
def now_with_mock_time
|
90
|
-
|
77
|
+
Time.now.send(:to_datetime)
|
91
78
|
end
|
92
79
|
|
93
80
|
# Alias now to now_with_mock_time
|
@@ -0,0 +1,77 @@
|
|
1
|
+
|
2
|
+
class Timecop
|
3
|
+
# A data class for carrying around "time movement" objects. Makes it easy to keep track of the time
|
4
|
+
# movements on a simple stack.
|
5
|
+
class TimeStackItem #:nodoc:
|
6
|
+
|
7
|
+
attr_reader :mock_type
|
8
|
+
def initialize(mock_type, *args)
|
9
|
+
@mock_type = mock_type
|
10
|
+
arg = args.shift
|
11
|
+
if arg.is_a?(Time)
|
12
|
+
@time = arg.getlocal
|
13
|
+
elsif Object.const_defined?(:DateTime) && arg.is_a?(DateTime)
|
14
|
+
offset_difference = Time.now_without_mock_time.utc_offset - rational_to_utc_offset(arg.offset)
|
15
|
+
@time = Time.local(arg.year, arg.month, arg.day, arg.hour, arg.min, arg.sec) + offset_difference
|
16
|
+
elsif Object.const_defined?(:Date) && arg.is_a?(Date)
|
17
|
+
@time = Time.local(arg.year, arg.month, arg.day, 0, 0, 0)
|
18
|
+
elsif args.empty? && arg.kind_of?(Integer)
|
19
|
+
@time = Time.now + arg
|
20
|
+
else # we'll just assume it's a list of y/m/h/d/m/s
|
21
|
+
year = arg || 0
|
22
|
+
month = args.shift || 1
|
23
|
+
day = args.shift || 1
|
24
|
+
hour = args.shift || 0
|
25
|
+
minute = args.shift || 0
|
26
|
+
second = args.shift || 0
|
27
|
+
@time = Time.local(year, month, day, hour, minute, second)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def year
|
32
|
+
@time.year
|
33
|
+
end
|
34
|
+
|
35
|
+
def month
|
36
|
+
@time.month
|
37
|
+
end
|
38
|
+
|
39
|
+
def day
|
40
|
+
@time.day
|
41
|
+
end
|
42
|
+
|
43
|
+
def hour
|
44
|
+
@time.hour
|
45
|
+
end
|
46
|
+
|
47
|
+
def min
|
48
|
+
@time.min
|
49
|
+
end
|
50
|
+
|
51
|
+
def sec
|
52
|
+
@time.sec
|
53
|
+
end
|
54
|
+
|
55
|
+
def time #:nodoc:
|
56
|
+
@time
|
57
|
+
end
|
58
|
+
|
59
|
+
def date
|
60
|
+
time.send(:to_date)
|
61
|
+
end
|
62
|
+
|
63
|
+
def datetime
|
64
|
+
time.send(:to_datetime)
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
def rational_to_utc_offset(rational)
|
69
|
+
((24.0 / rational.denominator) * rational.numerator) * (60 * 60)
|
70
|
+
end
|
71
|
+
|
72
|
+
def utc_offset_to_rational(utc_offset)
|
73
|
+
Rational(utc_offset, 24 * 60 * 60)
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
data/lib/timecop/timecop.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'singleton'
|
2
2
|
require File.join(File.dirname(__FILE__), 'time_extensions')
|
3
|
-
require File.join(File.dirname(__FILE__), '
|
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
|
@@ -77,10 +77,7 @@ class Timecop
|
|
77
77
|
end
|
78
78
|
|
79
79
|
def travel(mock_type, *args, &block) #:nodoc:
|
80
|
-
|
81
|
-
year, month, day, hour, minute, second = parse_travel_args(*args)
|
82
|
-
|
83
|
-
stack_item = StackItem.new(mock_type, year, month, day, hour, minute, second)
|
80
|
+
stack_item = TimeStackItem.new(mock_type, *args)
|
84
81
|
# perform our action
|
85
82
|
freeze_or_move(stack_item)
|
86
83
|
|
@@ -114,40 +111,9 @@ class Timecop
|
|
114
111
|
|
115
112
|
def freeze_or_move(stack_item) #:nodoc:
|
116
113
|
if stack_item.mock_type == :freeze
|
117
|
-
Time.freeze_time(
|
114
|
+
Time.freeze_time(stack_item.time)
|
118
115
|
else
|
119
|
-
Time.move_time(
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
def time_for_stack_item(stack_item) #:nodoc:
|
124
|
-
if Time.respond_to?(:zone) && !Time.zone.nil?
|
125
|
-
# ActiveSupport loaded
|
126
|
-
time = Time.zone.local(stack_item.year, stack_item.month, stack_item.day, stack_item.hour, stack_item.minute, stack_item.second)
|
127
|
-
else
|
128
|
-
# ActiveSupport not loaded
|
129
|
-
time = Time.local(stack_item.year, stack_item.month, stack_item.day, stack_item.hour, stack_item.minute, stack_item.second)
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
def parse_travel_args(*args) #:nodoc:
|
134
|
-
arg = args.shift
|
135
|
-
if arg.is_a?(Time) || (Object.const_defined?(:DateTime) && arg.is_a?(DateTime))
|
136
|
-
year, month, day, hour, minute, second = arg.year, arg.month, arg.day, arg.hour, arg.min, arg.sec
|
137
|
-
elsif Object.const_defined?(:Date) && arg.is_a?(Date)
|
138
|
-
year, month, day, hour, minute, second = arg.year, arg.month, arg.day, 0, 0, 0
|
139
|
-
#puts "#{year}-#{month}-#{day} #{hour}:#{minute}:#{second}"
|
140
|
-
elsif args.empty? && arg.kind_of?(Integer)
|
141
|
-
t = Time.now + arg
|
142
|
-
year, month, day, hour, minute, second = t.year, t.month, t.day, t.hour, t.min, t.sec
|
143
|
-
else # we'll just assume it's a list of y/m/h/d/m/s
|
144
|
-
year = arg || 0
|
145
|
-
month = args.shift || 1
|
146
|
-
day = args.shift || 1
|
147
|
-
hour = args.shift || 0
|
148
|
-
minute = args.shift || 0
|
149
|
-
second = args.shift || 0
|
116
|
+
Time.move_time(stack_item.time)
|
150
117
|
end
|
151
|
-
return year, month, day, hour, minute, second
|
152
118
|
end
|
153
119
|
end
|
data/test/run_tests.sh
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
#!/bin/sh
|
2
2
|
|
3
|
-
echo "\033[1;81m Running
|
4
|
-
ruby
|
3
|
+
echo "\033[1;81m Running test_time_stack_item...\033[0m"
|
4
|
+
ruby test_time_stack_item.rb || (echo "FAILED!!!!!!!!!!!!")
|
5
5
|
|
6
6
|
echo "\033[1;81m Running test_timecop_without_date...\033[0m"
|
7
7
|
ruby test_timecop_without_date.rb || (echo "FAILED!!!!!!!!!!!!")
|
8
8
|
|
9
|
+
echo "\033[1;81m Running test_timecop_without_date_but_with_time...\033[0m"
|
10
|
+
ruby test_timecop_without_date_but_with_time.rb || (echo "FAILED!!!!!!!!!!!!")
|
11
|
+
|
9
12
|
echo "\033[1;81m Running test_timecop...\033[0m"
|
10
13
|
ruby test_timecop.rb || (echo "FAILED!!!!!!!!!!!!")
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'test/unit'
|
3
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'timecop')
|
4
|
+
|
5
|
+
class TestTimeStackItem < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def test_new_with_time
|
8
|
+
t = Time.now
|
9
|
+
y, m, d, h, min, s = t.year, t.month, t.day, t.hour, t.min, t.sec
|
10
|
+
stack_item = Timecop::TimeStackItem.new(:freeze, t)
|
11
|
+
assert_equal y, stack_item.year
|
12
|
+
assert_equal m, stack_item.month
|
13
|
+
assert_equal d, stack_item.day
|
14
|
+
assert_equal h, stack_item.hour
|
15
|
+
assert_equal min, stack_item.min
|
16
|
+
assert_equal s, stack_item.sec
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_new_with_datetime_now
|
20
|
+
t = DateTime.now
|
21
|
+
y, m, d, h, min, s = t.year, t.month, t.day, t.hour, t.min, t.sec
|
22
|
+
stack_item = Timecop::TimeStackItem.new(:freeze, t)
|
23
|
+
assert_equal y, stack_item.year
|
24
|
+
assert_equal m, stack_item.month
|
25
|
+
assert_equal d, stack_item.day
|
26
|
+
assert_equal h, stack_item.hour
|
27
|
+
assert_equal min, stack_item.min
|
28
|
+
assert_equal s, stack_item.sec
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_new_with_datetime_in_different_timezone
|
32
|
+
t = DateTime.parse("2009-10-11 00:38:00 +0200")
|
33
|
+
stack_item = Timecop::TimeStackItem.new(:freeze, t)
|
34
|
+
assert_equal t, stack_item.datetime
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_new_with_date
|
38
|
+
date = Date.today
|
39
|
+
y, m, d, h, min, s = date.year, date.month, date.day, 0, 0, 0
|
40
|
+
stack_item = Timecop::TimeStackItem.new(:freeze, date)
|
41
|
+
assert_equal y, stack_item.year
|
42
|
+
assert_equal m, stack_item.month
|
43
|
+
assert_equal d, stack_item.day
|
44
|
+
assert_equal h, stack_item.hour
|
45
|
+
assert_equal min, stack_item.min
|
46
|
+
assert_equal s, stack_item.sec
|
47
|
+
end
|
48
|
+
|
49
|
+
# Due to the nature of this test (calling Time.now once in this test and
|
50
|
+
# once in #new), this test may fail when two subsequent calls
|
51
|
+
# to Time.now return a different second.
|
52
|
+
def test_new_with_integer
|
53
|
+
t = Time.now
|
54
|
+
y, m, d, h, min, s = t.year, t.month, t.day, t.hour, t.min, t.sec
|
55
|
+
stack_item = Timecop::TimeStackItem.new(:freeze, 0)
|
56
|
+
assert_equal y, stack_item.year
|
57
|
+
assert_equal m, stack_item.month
|
58
|
+
assert_equal d, stack_item.day
|
59
|
+
assert_equal h, stack_item.hour
|
60
|
+
assert_equal min, stack_item.min
|
61
|
+
assert_equal s, stack_item.sec
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_new_with_individual_arguments
|
65
|
+
y, m, d, h, min, s = 2008, 10, 10, 10, 10, 10
|
66
|
+
stack_item = Timecop::TimeStackItem.new(:freeze, y, m, d, h, min, s)
|
67
|
+
assert_equal y, stack_item.year
|
68
|
+
assert_equal m, stack_item.month
|
69
|
+
assert_equal d, stack_item.day
|
70
|
+
assert_equal h, stack_item.hour
|
71
|
+
assert_equal min, stack_item.min
|
72
|
+
assert_equal s, stack_item.sec
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_rational_to_utc_offset
|
76
|
+
assert_equal -14400, a_time_stack_item.send(:rational_to_utc_offset, Rational(-1, 6))
|
77
|
+
assert_equal -18000, a_time_stack_item.send(:rational_to_utc_offset, Rational(-5, 24))
|
78
|
+
assert_equal 0, a_time_stack_item.send(:rational_to_utc_offset, Rational(0, 1))
|
79
|
+
assert_equal 3600, a_time_stack_item.send(:rational_to_utc_offset, Rational(1, 24))
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_utc_offset_to_rational
|
83
|
+
assert_equal Rational(-1, 6), a_time_stack_item.send(:utc_offset_to_rational, -14400)
|
84
|
+
assert_equal Rational(-5, 24), a_time_stack_item.send(:utc_offset_to_rational, -18000)
|
85
|
+
assert_equal Rational(0, 1), a_time_stack_item.send(:utc_offset_to_rational, 0)
|
86
|
+
assert_equal Rational(1, 24), a_time_stack_item.send(:utc_offset_to_rational, 3600)
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
def a_time_stack_item
|
91
|
+
Timecop::TimeStackItem.new(:freeze, 2008, 1, 1, 0, 0, 0)
|
92
|
+
end
|
93
|
+
end
|
data/test/test_timecop.rb
CHANGED
@@ -67,16 +67,16 @@ class TestTimecop < Test::Unit::TestCase
|
|
67
67
|
t = Time.local(2008, 10, 10, 10, 10, 10)
|
68
68
|
Timecop.freeze(t) do
|
69
69
|
assert_equal t, Time.now
|
70
|
-
assert_equal DateTime.new(2008, 10, 10, 10, 10, 10), DateTime.now
|
70
|
+
assert_equal DateTime.new(2008, 10, 10, 10, 10, 10, local_offset), DateTime.now
|
71
71
|
assert_equal Date.new(2008, 10, 10), Date.today
|
72
72
|
end
|
73
73
|
assert_not_equal t, Time.now
|
74
|
-
assert_not_equal DateTime.new(2008, 10, 10, 10, 10, 10), DateTime.now
|
74
|
+
assert_not_equal DateTime.new(2008, 10, 10, 10, 10, 10, local_offset), DateTime.now
|
75
75
|
assert_not_equal Date.new(2008, 10, 10), Date.today
|
76
76
|
end
|
77
77
|
|
78
78
|
def test_freeze_with_datetime_instance_works_as_expected
|
79
|
-
t = DateTime.new(2008, 10, 10, 10, 10, 10)
|
79
|
+
t = DateTime.new(2008, 10, 10, 10, 10, 10, local_offset)
|
80
80
|
Timecop.freeze(t) do
|
81
81
|
assert_equal t, DateTime.now
|
82
82
|
assert_equal Time.local(2008, 10, 10, 10, 10, 10), Time.now
|
@@ -92,18 +92,18 @@ class TestTimecop < Test::Unit::TestCase
|
|
92
92
|
Timecop.freeze(d) do
|
93
93
|
assert_equal d, Date.today
|
94
94
|
assert_equal Time.local(2008, 10, 10, 0, 0, 0), Time.now
|
95
|
-
assert_equal DateTime.new(2008, 10, 10, 0, 0, 0), DateTime.now
|
95
|
+
assert_equal DateTime.new(2008, 10, 10, 0, 0, 0, local_offset), DateTime.now
|
96
96
|
end
|
97
97
|
assert_not_equal d, Date.today
|
98
98
|
assert_not_equal Time.local(2008, 10, 10, 0, 0, 0), Time.now
|
99
|
-
assert_not_equal DateTime.new(2008, 10, 10, 0, 0, 0), DateTime.now
|
99
|
+
assert_not_equal DateTime.new(2008, 10, 10, 0, 0, 0, local_offset), DateTime.now
|
100
100
|
end
|
101
101
|
|
102
102
|
def test_freeze_with_integer_instance_works_as_expected
|
103
103
|
t = Time.local(2008, 10, 10, 10, 10, 10)
|
104
104
|
Timecop.freeze(t) do
|
105
105
|
assert_equal t, Time.now
|
106
|
-
assert_equal DateTime.new(2008, 10, 10, 10, 10, 10), DateTime.now
|
106
|
+
assert_equal DateTime.new(2008, 10, 10, 10, 10, 10, local_offset), DateTime.now
|
107
107
|
assert_equal Date.new(2008, 10, 10), Date.today
|
108
108
|
Timecop.freeze(10) do
|
109
109
|
assert_equal t + 10, Time.now
|
@@ -155,6 +155,45 @@ class TestTimecop < Test::Unit::TestCase
|
|
155
155
|
end
|
156
156
|
end
|
157
157
|
|
158
|
+
def test_freeze_with_datetime_on_specific_timezone_during_dst
|
159
|
+
each_timezone do
|
160
|
+
t = DateTime.parse("2009-10-11 00:38:00 +0200")
|
161
|
+
assert_equal "+02:00", t.zone
|
162
|
+
Timecop.freeze(t) do
|
163
|
+
assert_equal t, DateTime.now.new_offset(t.offset), "Failed for timezone: #{ENV['TZ']}: #{t.to_s} not equal to #{DateTime.now.new_offset(t.offset).to_s}"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def test_freeze_with_datetime_on_specific_timezone_not_during_dst
|
169
|
+
each_timezone do
|
170
|
+
t = DateTime.parse("2009-12-11 00:38:00 +0200")
|
171
|
+
assert_equal "+02:00", t.zone
|
172
|
+
Timecop.freeze(t) do
|
173
|
+
assert_equal t, DateTime.now.new_offset(t.offset), "Failed for timezone: #{ENV['TZ']}"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def test_mocked_date_time_now_is_local
|
179
|
+
each_timezone do
|
180
|
+
t = DateTime.parse("2009-10-11 00:38:00 +0200")
|
181
|
+
Timecop.freeze(t) do
|
182
|
+
assert_equal local_offset, DateTime.now.offset, "Failed for timezone: #{ENV['TZ']}"
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def test_freeze_with_utc_time
|
188
|
+
each_timezone do
|
189
|
+
t = Time.utc(2008, 10, 10, 10, 10, 10)
|
190
|
+
local = t.getlocal
|
191
|
+
Timecop.freeze(t) do
|
192
|
+
assert_equal local, Time.now, "Failed for timezone: #{ENV['TZ']}"
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
158
197
|
def test_recursive_rebasing_maintains_each_context
|
159
198
|
t = Time.local(2008, 10, 10, 10, 10, 10)
|
160
199
|
Timecop.travel(2008, 10, 10, 10, 10, 10) do
|
@@ -218,13 +257,31 @@ class TestTimecop < Test::Unit::TestCase
|
|
218
257
|
assert times_effectively_equal(t_real, t_return)
|
219
258
|
end
|
220
259
|
|
260
|
+
private
|
221
261
|
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
(time1.to_i - time2.to_i).abs <= seconds_interval
|
228
|
-
end
|
262
|
+
# Tests to see that two times are within the given distance,
|
263
|
+
# in seconds, from each other.
|
264
|
+
def times_effectively_equal(time1, time2, seconds_interval = 1)
|
265
|
+
(time1.to_i - time2.to_i).abs <= seconds_interval
|
266
|
+
end
|
229
267
|
|
268
|
+
def local_offset
|
269
|
+
DateTime.now_without_mock_time.offset
|
270
|
+
end
|
271
|
+
|
272
|
+
TIMEZONES = ["Europe/Paris", "UTC", "EDT"]
|
273
|
+
|
274
|
+
def each_timezone
|
275
|
+
old_tz = ENV["TZ"]
|
276
|
+
|
277
|
+
begin
|
278
|
+
TIMEZONES.each do |timezone|
|
279
|
+
ENV["TZ"] = timezone
|
280
|
+
yield
|
281
|
+
end
|
282
|
+
ensure
|
283
|
+
ENV["TZ"] = old_tz
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
230
287
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
|
3
|
+
class TestTimecopWithoutDateButWithTime < Test::Unit::TestCase
|
4
|
+
TIMECOP_LIB = File.join(File.dirname(__FILE__), '..', 'lib', 'timecop')
|
5
|
+
|
6
|
+
def test_loads_properly_when_time_is_required_instead_of_date
|
7
|
+
assert_nothing_raised do
|
8
|
+
require "time"
|
9
|
+
require TIMECOP_LIB
|
10
|
+
end
|
11
|
+
end
|
12
|
+
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.3.
|
4
|
+
version: 0.3.4.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Trupiano
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-11-03 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -29,13 +29,14 @@ files:
|
|
29
29
|
- Rakefile
|
30
30
|
- VERSION.yml
|
31
31
|
- lib/timecop.rb
|
32
|
-
- lib/timecop/stack_item.rb
|
33
32
|
- lib/timecop/time_extensions.rb
|
33
|
+
- lib/timecop/time_stack_item.rb
|
34
34
|
- lib/timecop/timecop.rb
|
35
35
|
- test/run_tests.sh
|
36
|
+
- test/test_time_stack_item.rb
|
36
37
|
- test/test_timecop.rb
|
37
|
-
- test/test_timecop_internals.rb
|
38
38
|
- test/test_timecop_without_date.rb
|
39
|
+
- test/test_timecop_without_date_but_with_time.rb
|
39
40
|
has_rdoc: true
|
40
41
|
homepage: http://github.com/jtrupiano/timecop
|
41
42
|
licenses: []
|
@@ -53,9 +54,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
53
54
|
version:
|
54
55
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
56
|
requirements:
|
56
|
-
- - "
|
57
|
+
- - ">"
|
57
58
|
- !ruby/object:Gem::Version
|
58
|
-
version:
|
59
|
+
version: 1.3.1
|
59
60
|
version:
|
60
61
|
requirements: []
|
61
62
|
|
@@ -65,6 +66,7 @@ signing_key:
|
|
65
66
|
specification_version: 3
|
66
67
|
summary: 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.
|
67
68
|
test_files:
|
69
|
+
- test/test_time_stack_item.rb
|
68
70
|
- test/test_timecop.rb
|
69
|
-
- test/test_timecop_internals.rb
|
70
71
|
- test/test_timecop_without_date.rb
|
72
|
+
- test/test_timecop_without_date_but_with_time.rb
|
data/lib/timecop/stack_item.rb
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
|
2
|
-
class Timecop
|
3
|
-
# Simply a data class for carrying around "time movement" objects. Makes it easy to keep track of the time
|
4
|
-
# movements on a simple stack.
|
5
|
-
class StackItem #:nodoc:
|
6
|
-
|
7
|
-
attr_reader :mock_type, :year, :month, :day, :hour, :minute, :second
|
8
|
-
def initialize(mock_type, year, month, day, hour, minute, second)
|
9
|
-
@mock_type, @year, @month, @day, @hour, @minute, @second = mock_type, year, month, day, hour, minute, second
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
@@ -1,69 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'date'
|
3
|
-
require 'test/unit'
|
4
|
-
require File.join(File.dirname(__FILE__), '..', 'lib', 'timecop')
|
5
|
-
|
6
|
-
class TestTimecopInternals < Test::Unit::TestCase
|
7
|
-
|
8
|
-
def test_parse_travel_args_with_time
|
9
|
-
t = Time.now
|
10
|
-
y, m, d, h, min, s = t.year, t.month, t.day, t.hour, t.min, t.sec
|
11
|
-
ty, tm, td, th, tmin, ts = Timecop.instance().send(:parse_travel_args, t)
|
12
|
-
assert_equal y, ty
|
13
|
-
assert_equal m, tm
|
14
|
-
assert_equal d, td
|
15
|
-
assert_equal h, th
|
16
|
-
assert_equal min, tmin
|
17
|
-
assert_equal s, ts
|
18
|
-
end
|
19
|
-
|
20
|
-
def test_parse_travel_args_with_datetime
|
21
|
-
t = DateTime.now
|
22
|
-
y, m, d, h, min, s = t.year, t.month, t.day, t.hour, t.min, t.sec
|
23
|
-
ty, tm, td, th, tmin, ts = Timecop.instance().send(:parse_travel_args, t)
|
24
|
-
assert_equal y, ty
|
25
|
-
assert_equal m, tm
|
26
|
-
assert_equal d, td
|
27
|
-
assert_equal h, th
|
28
|
-
assert_equal min, tmin
|
29
|
-
assert_equal s, ts
|
30
|
-
end
|
31
|
-
|
32
|
-
def test_parse_travel_args_with_date
|
33
|
-
date = Date.today
|
34
|
-
y, m, d, h, min, s = date.year, date.month, date.day, 0, 0, 0
|
35
|
-
ty, tm, td, th, tmin, ts = Timecop.instance().send(:parse_travel_args, date)
|
36
|
-
assert_equal y, ty
|
37
|
-
assert_equal m, tm
|
38
|
-
assert_equal d, td
|
39
|
-
assert_equal h, th
|
40
|
-
assert_equal min, tmin
|
41
|
-
assert_equal s, ts
|
42
|
-
end
|
43
|
-
|
44
|
-
# Due to the nature of this test (calling Time.now once in this test and
|
45
|
-
# once in #parse_travel_args), this test may fail when two subsequent calls
|
46
|
-
# to Time.now return a different second.
|
47
|
-
def test_parse_travel_args_with_integer
|
48
|
-
t = Time.now
|
49
|
-
y, m, d, h, min, s = t.year, t.month, t.day, t.hour, t.min, t.sec
|
50
|
-
ty, tm, td, th, tmin, ts = Timecop.instance().send(:parse_travel_args, 0)
|
51
|
-
assert_equal y, ty
|
52
|
-
assert_equal m, tm
|
53
|
-
assert_equal d, td
|
54
|
-
assert_equal h, th
|
55
|
-
assert_equal min, tmin
|
56
|
-
assert_equal s, ts
|
57
|
-
end
|
58
|
-
|
59
|
-
def test_parse_travel_args_with_individual_arguments
|
60
|
-
y, m, d, h, min, s = 2008, 10, 10, 10, 10, 10
|
61
|
-
ty, tm, td, th, tmin, ts = Timecop.instance().send(:parse_travel_args, y, m, d, h, min, s)
|
62
|
-
assert_equal y, ty
|
63
|
-
assert_equal m, tm
|
64
|
-
assert_equal d, td
|
65
|
-
assert_equal h, th
|
66
|
-
assert_equal min, tmin
|
67
|
-
assert_equal s, ts
|
68
|
-
end
|
69
|
-
end
|