timecop 0.0.99 → 0.1.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/History.txt +0 -39
- data/Manifest.txt +0 -4
- data/README.txt +75 -0
- data/Rakefile +29 -27
- data/lib/timecop/time_extensions.rb +19 -37
- data/lib/timecop/timecop.rb +54 -131
- data/lib/timecop/version.rb +1 -1
- data/test/test_timecop.rb +54 -91
- data/test/test_timecop_with_rails.rb +22 -0
- data/test/test_timecop_without_date.rb +6 -105
- data/timecop.gemspec +35 -0
- metadata +27 -21
- data/LICENSE +0 -22
- data/README.textile +0 -68
- data/VERSION.yml +0 -4
- data/lib/timecop/stack_item.rb +0 -11
- data/test/run_tests.sh +0 -10
- data/test/test_timecop_internals.rb +0 -69
data/History.txt
CHANGED
@@ -1,42 +1,3 @@
|
|
1
|
-
=== 0.2.1 / 2009-03-06
|
2
|
-
* API Changes
|
3
|
-
|
4
|
-
* Introduced a 5th style of arguments to be passed into #travel and #freeze. Now, if you pass in a single integer value,
|
5
|
-
it will be interpreted as a relative offset in seconds from the current Time.now. Previously this was interpreted as
|
6
|
-
only the year, similar to calling Time.local(2008) --> Jan. 1, 2008. This is no longer the case.
|
7
|
-
|
8
|
-
* Documentation
|
9
|
-
|
10
|
-
* Moved to Textile for the README.
|
11
|
-
|
12
|
-
* Added documentation for the new feature, and fixed a few typos.
|
13
|
-
|
14
|
-
=== 0.2.0 / 2008-12-23
|
15
|
-
|
16
|
-
* API Changes
|
17
|
-
|
18
|
-
* Timecop#travel no longer freezes time. Rather, it computes the current offset between the new "now" and the real "now", and
|
19
|
-
returns times as if Time had continued to move forward
|
20
|
-
|
21
|
-
* Timecop#freeze now behaves exactly as the old Timecop#travel behaved. Unless you depended on the actual freezing of time
|
22
|
-
(which I think would be rare), you should be able to continue to use #travel without worry.
|
23
|
-
|
24
|
-
* Timecop#return is now exposed (previously Timecop#unset_all, but not well advertised). It will completely unmock time,
|
25
|
-
and will probably be rarely used outside of the actual implementation of this library.
|
26
|
-
|
27
|
-
* More Test Coverage
|
28
|
-
|
29
|
-
* Tests now explicitly cover the cases when the Date and DateTime objects are not loaded, and ensures proper functionality
|
30
|
-
in their absence and existence.
|
31
|
-
|
32
|
-
* Still haven't done regression testing against anything other than a few version of 1.8.6 (including REE). We should
|
33
|
-
probably try to get this tested on both 1.8.7 and 1.9.1.
|
34
|
-
|
35
|
-
* Documentation
|
36
|
-
|
37
|
-
* Fixed up a lot of the poorly-formatted rdoc syntax. The public API should now be properly published in the rdoc,
|
38
|
-
and the internals are omitted.
|
39
|
-
|
40
1
|
=== 0.1.0 / 2008-11-09
|
41
2
|
|
42
3
|
* Initial Feature Set
|
data/Manifest.txt
CHANGED
@@ -3,12 +3,8 @@ Manifest.txt
|
|
3
3
|
README.txt
|
4
4
|
Rakefile
|
5
5
|
lib/timecop.rb
|
6
|
-
lib/timecop/stack_item.rb
|
7
6
|
lib/timecop/time_extensions.rb
|
8
7
|
lib/timecop/timecop.rb
|
9
8
|
lib/timecop/version.rb
|
10
|
-
test/run_tests.sh
|
11
9
|
test/test_timecop.rb
|
12
|
-
test/test_timecop_internals.rb
|
13
|
-
test/test_timecop_without_date.rb
|
14
10
|
timecop.gemspec
|
data/README.txt
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
= timecop
|
2
|
+
|
3
|
+
* http://github.com/jtrupiano/timecop
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
A gem providing simple ways to (temporarily) override Time.now, Date.today, and DateTime.now. It provides "time travel" capabilities, making it dead simple to write test time-dependent code.
|
8
|
+
|
9
|
+
== FEATURES/PROBLEMS:
|
10
|
+
|
11
|
+
* Temporarily (or permanently if you prefer) change the concept of Time.now, DateTime.now (if defined), and Date.today (if defined)
|
12
|
+
* Timecop#travel api allows an argument to be passed in as one of: 1) Time instance, 2) DateTime instance, 3) Date instance,
|
13
|
+
4) individual arguments (year, month, day, hour, minute, second)
|
14
|
+
* Nested calls to Timecop#travel are supported -- each block will maintain it's interpretation of now.
|
15
|
+
|
16
|
+
== SYNOPSIS:
|
17
|
+
|
18
|
+
* Run a time-sensitive test:
|
19
|
+
<code>
|
20
|
+
joe = User.find(1)
|
21
|
+
joe.purchase_home()
|
22
|
+
assert !joe.mortgage_due?
|
23
|
+
# move ahead a month and assert that the mortgage is due
|
24
|
+
Timecop.travel(Date.today + 30) do
|
25
|
+
assert joe.mortgage_due?
|
26
|
+
end
|
27
|
+
</code>
|
28
|
+
|
29
|
+
* Set the time for the test environment of a rails app -- this is particularly helpful if your whole application
|
30
|
+
is time-sensitive. It allows you to build your test data at a single point in time, and to move in/out of that
|
31
|
+
time as appropriate (within your tests)
|
32
|
+
|
33
|
+
in config/environments/test.rb
|
34
|
+
|
35
|
+
<code>
|
36
|
+
config.after_initialize do
|
37
|
+
# Set Time.now to September 1, 2008 10:05:00 AM
|
38
|
+
t = Time.local(2008, 9, 1, 10, 5, 0)
|
39
|
+
Timecop.travel(t)
|
40
|
+
end
|
41
|
+
</code>
|
42
|
+
|
43
|
+
== REQUIREMENTS:
|
44
|
+
|
45
|
+
* None
|
46
|
+
|
47
|
+
== INSTALL:
|
48
|
+
|
49
|
+
* sudo gem install timecop (latest stable version from rubyforge)
|
50
|
+
* sudo gem install jtrupiano-timecop (HEAD of the repo from github)
|
51
|
+
|
52
|
+
== LICENSE:
|
53
|
+
|
54
|
+
(The MIT License)
|
55
|
+
|
56
|
+
Copyright (c) 2008 FIX
|
57
|
+
|
58
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
59
|
+
a copy of this software and associated documentation files (the
|
60
|
+
'Software'), to deal in the Software without restriction, including
|
61
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
62
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
63
|
+
permit persons to whom the Software is furnished to do so, subject to
|
64
|
+
the following conditions:
|
65
|
+
|
66
|
+
The above copyright notice and this permission notice shall be
|
67
|
+
included in all copies or substantial portions of the Software.
|
68
|
+
|
69
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
70
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
71
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
72
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
73
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
74
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
75
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
CHANGED
@@ -1,31 +1,33 @@
|
|
1
|
-
|
2
|
-
require 'rake/testtask'
|
3
|
-
require 'rake/rdoctask'
|
1
|
+
# -*- ruby -*-
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
s.authors = ["John Trupiano"]
|
15
|
-
s.files = FileList["[A-Z]*", "{bin,lib,test}/**/*"]
|
16
|
-
#s.add_dependency 'schacon-git'
|
17
|
-
end
|
18
|
-
rescue LoadError
|
19
|
-
puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
3
|
+
require 'rubygems'
|
4
|
+
require 'hoe'
|
5
|
+
require './lib/timecop/version.rb'
|
6
|
+
|
7
|
+
PKG_NAME = "timecop"
|
8
|
+
PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
|
9
|
+
version = Timecop::Version::STRING.dup
|
10
|
+
if ENV['SNAPSHOT'].to_i == 1
|
11
|
+
version << "." << Time.now.utc.strftime("%Y%m%d%H%M%S")
|
20
12
|
end
|
13
|
+
PKG_VERSION = version
|
14
|
+
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
21
15
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
16
|
+
Hoe.new(PKG_NAME, PKG_VERSION) do |p|
|
17
|
+
p.rubyforge_name = 'johntrupiano' # if different than lowercase project name
|
18
|
+
p.developer('John Trupiano', 'jtrupiano@gmail.com')
|
19
|
+
p.name = PKG_NAME
|
20
|
+
p.version = PKG_VERSION
|
21
|
+
#p.platform = Gem::Platform::RUBY
|
22
|
+
p.author = "John Trupiano"
|
23
|
+
p.email = "jtrupiano@gmail.com"
|
24
|
+
p.description = %q(A gem providing simple ways to temporarily override Time.now, Date.today, and DateTime.now. It provides "time travel" capabilities, making it dead simple to write test time-dependent code.)
|
25
|
+
p.summary = p.description # More details later??
|
26
|
+
p.remote_rdoc_dir = PKG_NAME # Release to /PKG_NAME
|
27
|
+
# p.changes = p.paragraphs_of('CHANGELOG', 0..1).join("\n\n")
|
28
|
+
p.need_zip = true
|
29
|
+
p.need_tar = false
|
31
30
|
end
|
31
|
+
|
32
|
+
# vim: syntax=Ruby
|
33
|
+
|
@@ -7,33 +7,11 @@
|
|
7
7
|
class Time
|
8
8
|
class << self
|
9
9
|
# Time we might be behaving as
|
10
|
-
|
11
|
-
|
12
|
-
@@mock_offset = nil
|
13
|
-
@@mock_time = nil
|
14
|
-
|
15
|
-
def mock_time
|
16
|
-
if !@@mock_offset.nil?
|
17
|
-
now_without_mock_time - @@mock_offset
|
18
|
-
else
|
19
|
-
@@mock_time
|
20
|
-
end
|
21
|
-
end
|
10
|
+
attr_reader :mock_time
|
22
11
|
|
23
12
|
# Set new time to pretend we are.
|
24
|
-
def
|
25
|
-
|
26
|
-
@@mock_offset = nil
|
27
|
-
end
|
28
|
-
|
29
|
-
def move_time(new_now)
|
30
|
-
@@mock_offset = new_now.nil? ? nil : (now_without_mock_time - new_now)
|
31
|
-
@@mock_time = nil
|
32
|
-
end
|
33
|
-
|
34
|
-
# Restores Time to system clock
|
35
|
-
def unmock!
|
36
|
-
move_time(nil)
|
13
|
+
def mock_time=(new_now)
|
14
|
+
@mock_time = new_now
|
37
15
|
end
|
38
16
|
|
39
17
|
# Alias the original now
|
@@ -52,12 +30,14 @@ end
|
|
52
30
|
if Object.const_defined?(:Date)
|
53
31
|
class Date
|
54
32
|
class << self
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
33
|
+
# Date we might be behaving as
|
34
|
+
attr_reader :mock_date
|
35
|
+
|
36
|
+
# Set new date to pretend we are.
|
37
|
+
def mock_date=(new_date)
|
38
|
+
@mock_date = new_date
|
59
39
|
end
|
60
|
-
|
40
|
+
|
61
41
|
# Alias the original today
|
62
42
|
alias_method :today_without_mock_date, :today
|
63
43
|
|
@@ -75,20 +55,22 @@ end
|
|
75
55
|
if Object.const_defined?(:DateTime)
|
76
56
|
class DateTime
|
77
57
|
class << self
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
58
|
+
# Time we might be behaving as
|
59
|
+
attr_reader :mock_time
|
60
|
+
|
61
|
+
# Set new time to pretend we are.
|
62
|
+
def mock_time=(new_now)
|
63
|
+
@mock_time = new_now
|
82
64
|
end
|
83
|
-
|
65
|
+
|
84
66
|
# Alias the original now
|
85
67
|
alias_method :now_without_mock_time, :now
|
86
|
-
|
68
|
+
|
87
69
|
# Define now_with_mock_time
|
88
70
|
def now_with_mock_time
|
89
71
|
mock_time || now_without_mock_time
|
90
72
|
end
|
91
|
-
|
73
|
+
|
92
74
|
# Alias now to now_with_mock_time
|
93
75
|
alias_method :now, :now_with_mock_time
|
94
76
|
end
|
data/lib/timecop/timecop.rb
CHANGED
@@ -1,17 +1,39 @@
|
|
1
|
-
require 'singleton'
|
2
1
|
require File.join(File.dirname(__FILE__), 'time_extensions')
|
3
|
-
require File.join(File.dirname(__FILE__), 'stack_item')
|
4
2
|
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
# * Optionally allows time travel to simulate a running clock, such time is not technically frozen.
|
9
|
-
#
|
10
|
-
# This is very useful when your app's functionality is dependent on time (e.g.
|
3
|
+
# 1. Wrapper class for manipulating the extensions to the Time, Date, and DateTime objects
|
4
|
+
# 2. Allows us to "freeze" time in our Ruby applications.
|
5
|
+
# 3. This is very useful when your app's functionality is dependent on time (e.g.
|
11
6
|
# anything that might expire). This will allow us to alter the return value of
|
12
7
|
# Date.today, Time.now, and DateTime.now, such that our application code _never_ has to change.
|
13
8
|
class Timecop
|
14
|
-
|
9
|
+
|
10
|
+
# Re-bases Time.now, Date.today and DateTime.now (if it exists) to use the time passed in.
|
11
|
+
# When using this method directly, it is up to the developer to call unset_all to return us
|
12
|
+
# to sanity.
|
13
|
+
#
|
14
|
+
# * If being consumed in a rails app, Time.zone.local will be used to instantiate the time.
|
15
|
+
# Otherwise, Time.local will be used.
|
16
|
+
def self.set_all(year, month, day, hour=0, minute=0, second=0)
|
17
|
+
if Time.respond_to?(:zone) && !Time.zone.nil?
|
18
|
+
# ActiveSupport loaded
|
19
|
+
time = Time.zone.local(year, month, day, hour, minute, second)
|
20
|
+
else
|
21
|
+
# ActiveSupport not loaded
|
22
|
+
time = Time.local(year, month, day, hour, minute, second)
|
23
|
+
end
|
24
|
+
|
25
|
+
Time.mock_time = time
|
26
|
+
Date.mock_date = Date.new(time.year, time.month, time.day) if Object.const_defined?(:Date)
|
27
|
+
DateTime.mock_time = DateTime.new(time.year, time.month, time.day, time.hour, time.min, time.sec) if Object.const_defined?(:DateTime)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Reverts back to system's Time.now, Date.today and DateTime.now (if it exists). If set_all
|
31
|
+
# was never called in the first place, this method will have no effect.
|
32
|
+
def self.unset_all
|
33
|
+
Date.mock_date = nil
|
34
|
+
DateTime.mock_time = nil if Object.const_defined?(:Date)
|
35
|
+
Time.mock_time = nil if Object.const_defined?(:DateTime)
|
36
|
+
end
|
15
37
|
|
16
38
|
# Allows you to run a block of code and "fake" a time throughout the execution of that block.
|
17
39
|
# This is particularly useful for writing test methods where the passage of time is critical to the business
|
@@ -21,148 +43,49 @@ class Timecop
|
|
21
43
|
# joe = User.find(1)
|
22
44
|
# joe.purchase_home()
|
23
45
|
# assert !joe.mortgage_due?
|
24
|
-
# Timecop.
|
46
|
+
# Timecop.travel(2008, 10, 5) do
|
25
47
|
# assert joe.mortgage_due?
|
26
48
|
# end
|
27
49
|
# </code>
|
28
50
|
#
|
29
|
-
#
|
30
|
-
# 1. Timecop.
|
31
|
-
# 2. Timecop.
|
32
|
-
# 3. Timecop.
|
33
|
-
# 4. Timecop.
|
51
|
+
# travel will respond to several different arguments:
|
52
|
+
# 1. Timecop.travel(time_inst)
|
53
|
+
# 2. Timecop.travel(datetime_inst)
|
54
|
+
# 3. Timecop.travel(date_inst)
|
55
|
+
# 4. Timecop.travel(year, month, day, hour=0, minute=0, second=0)
|
34
56
|
#
|
35
|
-
# When a block is also passed, Time.now, DateTime.now and Date.today are all reset to their
|
57
|
+
# When a block is also passed, the Time.now, DateTime.now and Date.today are all reset to their
|
36
58
|
# previous values. This allows us to nest multiple calls to Timecop.travel and have each block
|
37
59
|
# maintain it's concept of "now."
|
38
|
-
#
|
39
|
-
# * Note: Timecop.freeze will actually freeze time. This can cause unanticipated problems if
|
40
|
-
# benchmark or other timing calls are executed, which implicitly expect Time to actually move
|
41
|
-
# forward.
|
42
|
-
#
|
43
|
-
# * Rails Users: Be especially careful when setting this in your development environment in a
|
44
|
-
# rails project. Generators will load your environment, including the migration generator,
|
45
|
-
# which will lead to files being generated with the timestamp set by the Timecop.freeze call
|
46
|
-
# in your dev environment
|
47
|
-
def self.freeze(*args, &block)
|
48
|
-
instance().send(:travel, :freeze, *args, &block)
|
49
|
-
end
|
50
|
-
|
51
|
-
# Allows you to run a block of code and "fake" a time throughout the execution of that block.
|
52
|
-
# See Timecop#freeze for a sample of how to use (same exact usage syntax)
|
53
|
-
#
|
54
|
-
# * Note: Timecop.travel will not freeze time (as opposed to Timecop.freeze). This is a particularly
|
55
|
-
# good candidate for use in environment files in rails projects.
|
60
|
+
#def self.travel(year, month, day, hour=0, minute=0, second=0, &block)
|
56
61
|
def self.travel(*args, &block)
|
57
|
-
|
58
|
-
end
|
59
|
-
|
60
|
-
# Reverts back to system's Time.now, Date.today and DateTime.now (if it exists). If freeze_all or rebase_all
|
61
|
-
# was never called in the first place, this method will have no effect.
|
62
|
-
def self.return
|
63
|
-
instance().send(:unmock!)
|
64
|
-
end
|
62
|
+
year, month, day, hour, minute, second = parse_travel_args(*args)
|
65
63
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
$stderr.flush
|
70
|
-
self.return
|
71
|
-
end
|
72
|
-
|
73
|
-
protected
|
74
|
-
|
75
|
-
def initialize
|
76
|
-
@_stack = []
|
77
|
-
end
|
78
|
-
|
79
|
-
def travel(mock_type, *args, &block)
|
80
|
-
# parse the arguments, build our base time units
|
81
|
-
year, month, day, hour, minute, second = parse_travel_args(*args)
|
64
|
+
old_time = Time.mock_time
|
65
|
+
old_date = Date.mock_date if Object.const_defined?(:Date)
|
66
|
+
old_datetime = DateTime.mock_time if Object.const_defined?(:DateTime)
|
82
67
|
|
83
|
-
|
84
|
-
if mock_type == :freeze
|
85
|
-
freeze_all(year, month, day, hour, minute, second)
|
86
|
-
else
|
87
|
-
move_all(year, month, day, hour, minute, second)
|
88
|
-
end
|
89
|
-
# store this time traveling on our stack...
|
90
|
-
@_stack << StackItem.new(mock_type, year, month, day, hour, minute, second)
|
68
|
+
set_all(year, month, day, hour, minute, second)
|
91
69
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
# completely unmock if there's nothing to revert back to
|
100
|
-
unmock!
|
101
|
-
else
|
102
|
-
# or reinstantiate the new the top of the stack (could be a :freeze or a :move)
|
103
|
-
new_top = @_stack.last
|
104
|
-
if new_top.mock_type == :freeze
|
105
|
-
freeze_all(new_top.year, new_top.month, new_top.day, new_top.hour, new_top.minute, new_top.second)
|
106
|
-
else
|
107
|
-
move_all(new_top.year, new_top.month, new_top.day, new_top.hour, new_top.minute, new_top.second)
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
70
|
+
if block_given?
|
71
|
+
begin
|
72
|
+
yield
|
73
|
+
ensure
|
74
|
+
Time.mock_time = old_time
|
75
|
+
Date.mock_date = old_date if Object.const_defined?(:Date)
|
76
|
+
DateTime.mock_time = old_datetime if Object.const_defined?(:DateTime)
|
111
77
|
end
|
112
78
|
end
|
113
|
-
|
114
|
-
def unmock!
|
115
|
-
Time.unmock!
|
116
|
-
end
|
79
|
+
end
|
117
80
|
|
118
81
|
private
|
119
|
-
|
120
|
-
# Re-bases Time.now, Date.today and DateTime.now (if it exists) to use the time passed in.
|
121
|
-
# When using this method directly, it is up to the developer to call unset_all to return us
|
122
|
-
# to sanity.
|
123
|
-
#
|
124
|
-
# * If being consumed in a rails app, Time.zone.local will be used to instantiate the time.
|
125
|
-
# Otherwise, Time.local will be used.
|
126
|
-
def freeze_all(year, month, day, hour=0, minute=0, second=0)
|
127
|
-
if Time.respond_to?(:zone) && !Time.zone.nil?
|
128
|
-
# ActiveSupport loaded
|
129
|
-
time = Time.zone.local(year, month, day, hour, minute, second)
|
130
|
-
else
|
131
|
-
# ActiveSupport not loaded
|
132
|
-
time = Time.local(year, month, day, hour, minute, second)
|
133
|
-
end
|
134
|
-
|
135
|
-
Time.freeze_time(time)
|
136
|
-
end
|
137
|
-
|
138
|
-
# Re-bases Time.now, Date.today and DateTime.now to use the time passed in and to continue moving time
|
139
|
-
# forward. When using this method directly, it is up to the developer to call return to return us to
|
140
|
-
# sanity.
|
141
|
-
#
|
142
|
-
# * If being consumed in a rails app, Time.zone.local will be used to instantiate the time.
|
143
|
-
# Otherwise, Time.local will be used.
|
144
|
-
def move_all(year, month, day, hour=0, minute=0, second=0)
|
145
|
-
if Time.respond_to?(:zone) && !Time.zone.nil?
|
146
|
-
# ActiveSupport loaded
|
147
|
-
time = Time.zone.local(year, month, day, hour, minute, second)
|
148
|
-
else
|
149
|
-
# ActiveSupport not loaded
|
150
|
-
time = Time.local(year, month, day, hour, minute, second)
|
151
|
-
end
|
152
|
-
|
153
|
-
Time.move_time(time)
|
154
|
-
end
|
155
|
-
|
156
|
-
def parse_travel_args(*args)
|
82
|
+
def self.parse_travel_args(*args)
|
157
83
|
arg = args.shift
|
158
84
|
if arg.is_a?(Time) || (Object.const_defined?(:DateTime) && arg.is_a?(DateTime))
|
159
85
|
year, month, day, hour, minute, second = arg.year, arg.month, arg.day, arg.hour, arg.min, arg.sec
|
160
86
|
elsif Object.const_defined?(:Date) && arg.is_a?(Date)
|
161
87
|
year, month, day, hour, minute, second = arg.year, arg.month, arg.day, 0, 0, 0
|
162
|
-
|
163
|
-
elsif args.empty? && arg.kind_of?(Integer)
|
164
|
-
t = Time.now + arg
|
165
|
-
year, month, day, hour, minute, second = t.year, t.month, t.day, t.hour, t.min, t.sec
|
88
|
+
puts "#{year}-#{month}-#{day} #{hour}:#{minute}:#{second}"
|
166
89
|
else # we'll just assume it's a list of y/m/h/d/m/s
|
167
90
|
year = arg || 0
|
168
91
|
month = args.shift || 1
|
data/lib/timecop/version.rb
CHANGED
data/test/test_timecop.rb
CHANGED
@@ -11,37 +11,37 @@ class TestTimecop < Test::Unit::TestCase
|
|
11
11
|
|
12
12
|
# just in case...let's really make sure that Timecop is disabled between tests...
|
13
13
|
def teardown
|
14
|
-
Timecop.
|
14
|
+
Timecop.unset_all
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
17
|
+
def test_travel_changes_and_resets_time
|
18
18
|
# depending on how we're invoked (individually or via the rake test suite)
|
19
19
|
assert !Time.respond_to?(:zone) || Time.zone.nil?
|
20
20
|
|
21
21
|
t = Time.local(2008, 10, 10, 10, 10, 10)
|
22
22
|
assert_not_equal t, Time.now
|
23
|
-
Timecop.
|
23
|
+
Timecop.travel(2008, 10, 10, 10, 10, 10) do
|
24
24
|
assert_equal t, Time.now
|
25
25
|
end
|
26
26
|
assert_not_equal t, Time.now
|
27
27
|
end
|
28
28
|
|
29
|
-
def
|
29
|
+
def test_recursive_travel
|
30
30
|
t = Time.local(2008, 10, 10, 10, 10, 10)
|
31
|
-
Timecop.
|
31
|
+
Timecop.travel(2008, 10, 10, 10, 10, 10) do
|
32
32
|
assert_equal t, Time.now
|
33
33
|
t2 = Time.local(2008, 9, 9, 9, 9, 9)
|
34
|
-
Timecop.
|
34
|
+
Timecop.travel(2008, 9, 9, 9, 9, 9) do
|
35
35
|
assert_equal t2, Time.now
|
36
36
|
end
|
37
37
|
assert_equal t, Time.now
|
38
38
|
end
|
39
|
-
|
39
|
+
assert_nil Time.send(:mock_time)
|
40
40
|
end
|
41
41
|
|
42
|
-
def
|
42
|
+
def test_travel_with_time_instance_works_as_expected
|
43
43
|
t = Time.local(2008, 10, 10, 10, 10, 10)
|
44
|
-
Timecop.
|
44
|
+
Timecop.travel(t) do
|
45
45
|
assert_equal t, Time.now
|
46
46
|
assert_equal DateTime.new(2008, 10, 10, 10, 10, 10), DateTime.now
|
47
47
|
assert_equal Date.new(2008, 10, 10), Date.today
|
@@ -51,9 +51,9 @@ class TestTimecop < Test::Unit::TestCase
|
|
51
51
|
assert_not_equal Date.new(2008, 10, 10), Date.today
|
52
52
|
end
|
53
53
|
|
54
|
-
def
|
54
|
+
def test_travel_with_datetime_instance_works_as_expected
|
55
55
|
t = DateTime.new(2008, 10, 10, 10, 10, 10)
|
56
|
-
Timecop.
|
56
|
+
Timecop.travel(t) do
|
57
57
|
assert_equal t, DateTime.now
|
58
58
|
assert_equal Time.local(2008, 10, 10, 10, 10, 10), Time.now
|
59
59
|
assert_equal Date.new(2008, 10, 10), Date.today
|
@@ -63,9 +63,9 @@ class TestTimecop < Test::Unit::TestCase
|
|
63
63
|
assert_not_equal Date.new(2008, 10, 10), Date.today
|
64
64
|
end
|
65
65
|
|
66
|
-
def
|
66
|
+
def test_travel_with_date_instance_works_as_expected
|
67
67
|
d = Date.new(2008, 10, 10)
|
68
|
-
Timecop.
|
68
|
+
Timecop.travel(d) do
|
69
69
|
assert_equal d, Date.today
|
70
70
|
assert_equal Time.local(2008, 10, 10, 0, 0, 0), Time.now
|
71
71
|
assert_equal DateTime.new(2008, 10, 10, 0, 0, 0), DateTime.now
|
@@ -75,27 +75,10 @@ class TestTimecop < Test::Unit::TestCase
|
|
75
75
|
assert_not_equal DateTime.new(2008, 10, 10, 0, 0, 0), DateTime.now
|
76
76
|
end
|
77
77
|
|
78
|
-
def
|
79
|
-
t = Time.local(2008, 10, 10, 10, 10, 10)
|
80
|
-
Timecop.freeze(t) do
|
81
|
-
assert_equal t, Time.now
|
82
|
-
assert_equal DateTime.new(2008, 10, 10, 10, 10, 10), DateTime.now
|
83
|
-
assert_equal Date.new(2008, 10, 10), Date.today
|
84
|
-
Timecop.freeze(10) do
|
85
|
-
assert_equal t + 10, Time.now
|
86
|
-
assert_equal Time.local(2008, 10, 10, 10, 10, 20), Time.now
|
87
|
-
assert_equal Date.new(2008, 10, 10), Date.today
|
88
|
-
end
|
89
|
-
end
|
90
|
-
assert_not_equal t, Time.now
|
91
|
-
assert_not_equal DateTime.new(2008, 10, 10, 10, 10, 10), DateTime.now
|
92
|
-
assert_not_equal Date.new(2008, 10, 10), Date.today
|
93
|
-
end
|
94
|
-
|
95
|
-
def test_exception_thrown_in_freeze_block_properly_resets_time
|
78
|
+
def test_exception_thrown_in_travel_block_properly_resets_time
|
96
79
|
t = Time.local(2008, 10, 10, 10, 10, 10)
|
97
80
|
begin
|
98
|
-
Timecop.
|
81
|
+
Timecop.travel(t) do
|
99
82
|
assert_equal t, Time.now
|
100
83
|
raise "blah exception"
|
101
84
|
end
|
@@ -105,71 +88,51 @@ class TestTimecop < Test::Unit::TestCase
|
|
105
88
|
end
|
106
89
|
end
|
107
90
|
|
108
|
-
def test_freeze_freezes_time
|
109
|
-
t = Time.local(2008, 10, 10, 10, 10, 10)
|
110
|
-
now = Time.now
|
111
|
-
Timecop.freeze(t) do
|
112
|
-
#assert Time.now < now, "If we had failed to freeze, time would have proceeded, which is what appears to have happened."
|
113
|
-
new_t, new_d, new_dt = Time.now, Date.today, DateTime.now
|
114
|
-
assert_equal t, new_t, "Failed to freeze time." # 2 seconds
|
115
|
-
#sleep(10)
|
116
|
-
assert_equal new_t, Time.now
|
117
|
-
assert_equal new_d, Date.today
|
118
|
-
assert_equal new_dt, DateTime.now
|
119
|
-
end
|
120
|
-
end
|
121
91
|
|
122
|
-
def
|
123
|
-
t = Time.
|
124
|
-
|
125
|
-
Timecop.
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
92
|
+
def test_parse_travel_args_with_time
|
93
|
+
t = Time.now
|
94
|
+
y, m, d, h, min, s = t.year, t.month, t.day, t.hour, t.min, t.sec
|
95
|
+
ty, tm, td, th, tmin, ts = Timecop.send(:parse_travel_args, t)
|
96
|
+
assert_equal y, ty
|
97
|
+
assert_equal m, tm
|
98
|
+
assert_equal d, td
|
99
|
+
assert_equal h, th
|
100
|
+
assert_equal min, tmin
|
101
|
+
assert_equal s, ts
|
132
102
|
end
|
133
103
|
|
134
|
-
def
|
135
|
-
t =
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
end
|
145
|
-
assert_nil Time.send(:mock_time)
|
104
|
+
def test_parse_travel_args_with_datetime
|
105
|
+
t = DateTime.now
|
106
|
+
y, m, d, h, min, s = t.year, t.month, t.day, t.hour, t.min, t.sec
|
107
|
+
ty, tm, td, th, tmin, ts = Timecop.send(:parse_travel_args, t)
|
108
|
+
assert_equal y, ty
|
109
|
+
assert_equal m, tm
|
110
|
+
assert_equal d, td
|
111
|
+
assert_equal h, th
|
112
|
+
assert_equal min, tmin
|
113
|
+
assert_equal s, ts
|
146
114
|
end
|
147
115
|
|
148
|
-
def
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
assert_nil Time.send(:mock_time)
|
116
|
+
def test_parse_travel_args_with_date
|
117
|
+
date = Date.today
|
118
|
+
y, m, d, h, min, s = date.year, date.month, date.day, 0, 0, 0
|
119
|
+
ty, tm, td, th, tmin, ts = Timecop.send(:parse_travel_args, date)
|
120
|
+
assert_equal y, ty
|
121
|
+
assert_equal m, tm
|
122
|
+
assert_equal d, td
|
123
|
+
assert_equal h, th
|
124
|
+
assert_equal min, tmin
|
125
|
+
assert_equal s, ts
|
159
126
|
end
|
160
127
|
|
161
|
-
def
|
162
|
-
|
163
|
-
Timecop.
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
assert_equal t, Time.now
|
171
|
-
end
|
172
|
-
assert_nil Time.send(:mock_time)
|
128
|
+
def test_parse_travel_args_with_individual_arguments
|
129
|
+
y, m, d, h, min, s = 2008, 10, 10, 10, 10, 10
|
130
|
+
ty, tm, td, th, tmin, ts = Timecop.send(:parse_travel_args, y, m, d, h, min, s)
|
131
|
+
assert_equal y, ty
|
132
|
+
assert_equal m, tm
|
133
|
+
assert_equal d, td
|
134
|
+
assert_equal h, th
|
135
|
+
assert_equal min, tmin
|
136
|
+
assert_equal s, ts
|
173
137
|
end
|
174
|
-
|
175
138
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
gem "activesupport", ">= 2.1.0"
|
6
|
+
require 'activesupport'
|
7
|
+
|
8
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'timecop')
|
9
|
+
|
10
|
+
class TestTimecopWithRails < Test::Unit::TestCase
|
11
|
+
|
12
|
+
def test_travel_changes_and_resets_time
|
13
|
+
Time.zone = 'Eastern Time (US & Canada)'
|
14
|
+
t = Time.zone.local(2008, 10, 10, 10, 10, 10)
|
15
|
+
assert_not_equal t, Time.now
|
16
|
+
Timecop.travel(2008, 10, 10, 10, 10, 10) do
|
17
|
+
assert_equal t, Time.now
|
18
|
+
end
|
19
|
+
assert_not_equal t, Time.now
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -2,119 +2,20 @@
|
|
2
2
|
require 'test/unit'
|
3
3
|
require File.join(File.dirname(__FILE__), '..', 'lib', 'timecop')
|
4
4
|
|
5
|
-
class
|
5
|
+
class TestTimecopWithoutDate < Test::Unit::TestCase
|
6
6
|
|
7
|
-
def
|
8
|
-
assert !Object.const_defined?(:Date)
|
9
|
-
assert !Object.const_defined?(:DateTime)
|
10
|
-
end
|
11
|
-
|
12
|
-
# just in case...let's really make sure that Timecop is disabled between tests...
|
13
|
-
def teardown
|
14
|
-
Timecop.return
|
15
|
-
end
|
16
|
-
|
17
|
-
def test_freeze_changes_and_resets_time
|
7
|
+
def test_travel_changes_and_resets_time
|
18
8
|
# depending on how we're invoked (individually or via the rake test suite)
|
19
|
-
assert
|
9
|
+
assert Object.const_defined?(:Time)
|
10
|
+
#assert !Object.const_defined?(:Date)
|
11
|
+
assert !Object.const_defined?(:DateTime)
|
20
12
|
|
21
13
|
t = Time.local(2008, 10, 10, 10, 10, 10)
|
22
14
|
assert_not_equal t, Time.now
|
23
|
-
Timecop.
|
15
|
+
Timecop.travel(2008, 10, 10, 10, 10, 10) do
|
24
16
|
assert_equal t, Time.now
|
25
17
|
end
|
26
18
|
assert_not_equal t, Time.now
|
27
19
|
end
|
28
20
|
|
29
|
-
def test_recursive_freeze
|
30
|
-
t = Time.local(2008, 10, 10, 10, 10, 10)
|
31
|
-
Timecop.freeze(2008, 10, 10, 10, 10, 10) do
|
32
|
-
assert_equal t, Time.now
|
33
|
-
t2 = Time.local(2008, 9, 9, 9, 9, 9)
|
34
|
-
Timecop.freeze(2008, 9, 9, 9, 9, 9) do
|
35
|
-
assert_equal t2, Time.now
|
36
|
-
end
|
37
|
-
assert_equal t, Time.now
|
38
|
-
end
|
39
|
-
assert_nil Time.send(:mock_time)
|
40
|
-
end
|
41
|
-
|
42
|
-
def test_exception_thrown_in_freeze_block_properly_resets_time
|
43
|
-
t = Time.local(2008, 10, 10, 10, 10, 10)
|
44
|
-
begin
|
45
|
-
Timecop.freeze(t) do
|
46
|
-
assert_equal t, Time.now
|
47
|
-
raise "blah exception"
|
48
|
-
end
|
49
|
-
rescue
|
50
|
-
assert_not_equal t, Time.now
|
51
|
-
assert_nil Time.send(:mock_time)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def test_freeze_freezes_time
|
56
|
-
t = Time.local(2008, 10, 10, 10, 10, 10)
|
57
|
-
now = Time.now
|
58
|
-
Timecop.freeze(t) do
|
59
|
-
#assert Time.now < now, "If we had failed to freeze, time would have proceeded, which is what appears to have happened."
|
60
|
-
new_t = Time.now
|
61
|
-
assert_equal t, new_t, "Failed to change move time." # 2 seconds
|
62
|
-
#sleep(10)
|
63
|
-
assert_equal new_t, Time.now
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def test_travel_keeps_time_moving
|
68
|
-
t = Time.local(2008, 10, 10, 10, 10, 10)
|
69
|
-
now = Time.now
|
70
|
-
Timecop.travel(t) do
|
71
|
-
#assert Time.now < now, "If we had failed to freeze, time would have proceeded, which is what appears to have happened."
|
72
|
-
assert Time.now - t < 2000, "Looks like we failed to actually travel time" # 2 seconds
|
73
|
-
new_t = Time.now
|
74
|
-
#sleep(10)
|
75
|
-
assert_not_equal new_t, Time.now
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def test_recursive_rebasing_maintains_each_context
|
80
|
-
t = Time.local(2008, 10, 10, 10, 10, 10)
|
81
|
-
Timecop.travel(2008, 10, 10, 10, 10, 10) do
|
82
|
-
assert((t - Time.now).abs < 50, "Failed to travel time.")
|
83
|
-
t2 = Time.local(2008, 9, 9, 9, 9, 9)
|
84
|
-
Timecop.travel(2008, 9, 9, 9, 9, 9) do
|
85
|
-
assert((t2 - Time.now) < 50, "Failed to travel time.")
|
86
|
-
assert((t - Time.now) > 1000, "Failed to travel time.")
|
87
|
-
end
|
88
|
-
assert((t - Time.now).abs < 2000, "Failed to restore previously-traveled time.")
|
89
|
-
end
|
90
|
-
assert_nil Time.send(:mock_time)
|
91
|
-
end
|
92
|
-
|
93
|
-
def test_recursive_travel_then_freeze
|
94
|
-
t = Time.local(2008, 10, 10, 10, 10, 10)
|
95
|
-
Timecop.travel(2008, 10, 10, 10, 10, 10) do
|
96
|
-
assert((t - Time.now).abs < 50, "Failed to travel time.")
|
97
|
-
t2 = Time.local(2008, 9, 9, 9, 9, 9)
|
98
|
-
Timecop.freeze(2008, 9, 9, 9, 9, 9) do
|
99
|
-
assert_equal t2, Time.now
|
100
|
-
end
|
101
|
-
assert((t - Time.now).abs < 2000, "Failed to restore previously-traveled time.")
|
102
|
-
end
|
103
|
-
assert_nil Time.send(:mock_time)
|
104
|
-
end
|
105
|
-
|
106
|
-
def test_recursive_freeze_then_travel
|
107
|
-
t = Time.local(2008, 10, 10, 10, 10, 10)
|
108
|
-
Timecop.freeze(t) do
|
109
|
-
assert_equal t, Time.now
|
110
|
-
t2 = Time.local(2008, 9, 9, 9, 9, 9)
|
111
|
-
Timecop.travel(t2) do
|
112
|
-
assert((t2 - Time.now) < 50, "Failed to travel time.")
|
113
|
-
assert((t - Time.now) > 1000, "Failed to travel time.")
|
114
|
-
end
|
115
|
-
assert_equal t, Time.now
|
116
|
-
end
|
117
|
-
assert_nil Time.send(:mock_time)
|
118
|
-
end
|
119
|
-
|
120
21
|
end
|
data/timecop.gemspec
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{timecop}
|
5
|
+
s.version = "0.1.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["John Trupiano"]
|
9
|
+
s.date = %q{2008-11-09}
|
10
|
+
s.description = %q{A gem providing simple ways to temporarily override Time.now, Date.today, and DateTime.now. It provides "time travel" capabilities, making it dead simple to write test time-dependent code.}
|
11
|
+
s.email = %q{jtrupiano@gmail.com}
|
12
|
+
s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt"]
|
13
|
+
s.files = ["History.txt", "Manifest.txt", "README.txt", "Rakefile", "lib/timecop.rb", "lib/timecop/time_extensions.rb", "lib/timecop/timecop.rb", "lib/timecop/version.rb", "test/test_timecop.rb", "timecop.gemspec", "test/test_timecop_with_rails.rb", "test/test_timecop_without_date.rb"]
|
14
|
+
s.has_rdoc = true
|
15
|
+
s.homepage = %q{http://github.com/jtrupiano/timecop}
|
16
|
+
s.rdoc_options = ["--main", "README.txt"]
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
s.rubyforge_project = %q{johntrupiano}
|
19
|
+
s.rubygems_version = %q{1.3.1}
|
20
|
+
s.summary = %q{A gem providing simple ways to temporarily override Time.now, Date.today, and DateTime.now. It provides "time travel" capabilities, making it dead simple to write test time-dependent code.}
|
21
|
+
s.test_files = ["test/test_timecop.rb", "test/test_timecop_with_rails.rb", "test/test_timecop_without_date.rb"]
|
22
|
+
|
23
|
+
if s.respond_to? :specification_version then
|
24
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
25
|
+
s.specification_version = 2
|
26
|
+
|
27
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
28
|
+
s.add_development_dependency(%q<hoe>, [">= 1.8.2"])
|
29
|
+
else
|
30
|
+
s.add_dependency(%q<hoe>, [">= 1.8.2"])
|
31
|
+
end
|
32
|
+
else
|
33
|
+
s.add_dependency(%q<hoe>, [">= 1.8.2"])
|
34
|
+
end
|
35
|
+
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.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Trupiano
|
@@ -9,42 +9,46 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2008-11-09 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
16
|
-
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: hoe
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.8.2
|
24
|
+
version:
|
25
|
+
description: A gem providing simple ways to temporarily override Time.now, Date.today, and DateTime.now. It provides "time travel" capabilities, making it dead simple to write test time-dependent code.
|
17
26
|
email: jtrupiano@gmail.com
|
18
27
|
executables: []
|
19
28
|
|
20
29
|
extensions: []
|
21
30
|
|
22
31
|
extra_rdoc_files:
|
23
|
-
-
|
24
|
-
-
|
32
|
+
- History.txt
|
33
|
+
- Manifest.txt
|
34
|
+
- README.txt
|
25
35
|
files:
|
26
36
|
- History.txt
|
27
|
-
- LICENSE
|
28
37
|
- Manifest.txt
|
38
|
+
- README.txt
|
29
39
|
- Rakefile
|
30
|
-
-
|
31
|
-
- VERSION.yml
|
32
|
-
- lib/timecop
|
33
|
-
- lib/timecop/stack_item.rb
|
40
|
+
- lib/timecop.rb
|
34
41
|
- lib/timecop/time_extensions.rb
|
35
42
|
- lib/timecop/timecop.rb
|
36
43
|
- lib/timecop/version.rb
|
37
|
-
- lib/timecop.rb
|
38
|
-
- test/run_tests.sh
|
39
44
|
- test/test_timecop.rb
|
40
|
-
-
|
41
|
-
- test/test_timecop_without_date.rb
|
45
|
+
- timecop.gemspec
|
42
46
|
has_rdoc: true
|
43
47
|
homepage: http://github.com/jtrupiano/timecop
|
44
48
|
post_install_message:
|
45
49
|
rdoc_options:
|
46
|
-
- --
|
47
|
-
-
|
50
|
+
- --main
|
51
|
+
- README.txt
|
48
52
|
require_paths:
|
49
53
|
- lib
|
50
54
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -65,6 +69,8 @@ rubyforge_project: johntrupiano
|
|
65
69
|
rubygems_version: 1.3.1
|
66
70
|
signing_key:
|
67
71
|
specification_version: 2
|
68
|
-
summary: A gem providing simple ways to temporarily override Time.now, Date.today, and DateTime.now. It provides "time travel" capabilities, making it dead simple to test time-dependent code.
|
69
|
-
test_files:
|
70
|
-
|
72
|
+
summary: A gem providing simple ways to temporarily override Time.now, Date.today, and DateTime.now. It provides "time travel" capabilities, making it dead simple to write test time-dependent code.
|
73
|
+
test_files:
|
74
|
+
- test/test_timecop.rb
|
75
|
+
- test/test_timecop_with_rails.rb
|
76
|
+
- test/test_timecop_without_date.rb
|
data/LICENSE
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
(The MIT License)
|
2
|
-
|
3
|
-
Copyright (c) 2008
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
-
a copy of this software and associated documentation files (the
|
7
|
-
'Software'), to deal in the Software without restriction, including
|
8
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
-
permit persons to whom the Software is furnished to do so, subject to
|
11
|
-
the following conditions:
|
12
|
-
|
13
|
-
The above copyright notice and this permission notice shall be
|
14
|
-
included in all copies or substantial portions of the Software.
|
15
|
-
|
16
|
-
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
17
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
19
|
-
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
20
|
-
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
21
|
-
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
22
|
-
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.textile
DELETED
@@ -1,68 +0,0 @@
|
|
1
|
-
h1. timecop
|
2
|
-
|
3
|
-
* http://github.com/jtrupiano/timecop
|
4
|
-
|
5
|
-
h2. DESCRIPTION
|
6
|
-
|
7
|
-
A gem providing simple ways to mock Time.now, Date.today, and DateTime.now. It provides "time travel" and "time freezing" capabilities, making it dead simple to test time-dependent code.
|
8
|
-
|
9
|
-
h2. FEATURES
|
10
|
-
|
11
|
-
* Temporarily (or permanently if you prefer) change the concept of Time.now, DateTime.now, and Date.today
|
12
|
-
* Timecop api allows arguments to be passed into #freeze and #travel as one of the following:
|
13
|
-
# Time instance
|
14
|
-
# DateTime instance
|
15
|
-
# Date instance
|
16
|
-
# individual arguments (year, month, day, hour, minute, second)
|
17
|
-
# a single integer argument that is interpreted as an offset in seconds from Time.now
|
18
|
-
|
19
|
-
* Nested calls to Timecop#travel and Timecop#freeze are supported -- each block will maintain it's interpretation of now.
|
20
|
-
|
21
|
-
h2. SHORTCOMINGS
|
22
|
-
|
23
|
-
* Only fully tested on the 1.8.6 Ruby implementations. 1.8.7 and 1.9.1 should be tested, as well as other flavors (jruby, etc.)
|
24
|
-
|
25
|
-
h2. SYNOPSIS
|
26
|
-
|
27
|
-
Run a time-sensitive test
|
28
|
-
|
29
|
-
<pre>
|
30
|
-
<code>
|
31
|
-
joe = User.find(1)
|
32
|
-
joe.purchase_home()
|
33
|
-
assert !joe.mortgage_due?
|
34
|
-
# move ahead a month and assert that the mortgage is due
|
35
|
-
Timecop.freeze(Date.today + 30) do
|
36
|
-
assert joe.mortgage_due?
|
37
|
-
end
|
38
|
-
</code>
|
39
|
-
</pre>
|
40
|
-
|
41
|
-
Set the time for the test environment of a rails app -- this is particularly helpful if your whole application is time-sensitive. It allows you to build your test data at a single point in time, and to move in/out of that time as appropriate (within your tests)
|
42
|
-
|
43
|
-
in config/environments/test.rb
|
44
|
-
|
45
|
-
<pre>
|
46
|
-
<code>
|
47
|
-
config.after_initialize do
|
48
|
-
# Set Time.now to September 1, 2008 10:05:00 AM
|
49
|
-
t = Time.local(2008, 9, 1, 10, 5, 0)
|
50
|
-
Timecop.travel(t)
|
51
|
-
end
|
52
|
-
</code>
|
53
|
-
</pre>
|
54
|
-
|
55
|
-
h2. REQUIREMENTS
|
56
|
-
|
57
|
-
* None
|
58
|
-
|
59
|
-
h2. INSTALL
|
60
|
-
|
61
|
-
* sudo gem install timecop (latest stable version from rubyforge)
|
62
|
-
* sudo gem install jtrupiano-timecop (HEAD of the repo from github)
|
63
|
-
|
64
|
-
h2. REFERENCES
|
65
|
-
|
66
|
-
* "0.1.0 release":http://blog.smartlogicsolutions.com/2008/11/19/timecop-freeze-time-in-ruby-for-better-testing/
|
67
|
-
* "0.2.0 release":http://blog.smartlogicsolutions.com/2008/12/24/timecop-2-released-freeze-and-rebase-time-ruby/
|
68
|
-
|
data/VERSION.yml
DELETED
data/lib/timecop/stack_item.rb
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
|
2
|
-
# Simply 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 StackItem
|
5
|
-
|
6
|
-
attr_reader :mock_type, :year, :month, :day, :hour, :minute, :second
|
7
|
-
def initialize(mock_type, year, month, day, hour, minute, second)
|
8
|
-
@mock_type, @year, @month, @day, @hour, @minute, @second = mock_type, year, month, day, hour, minute, second
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
data/test/run_tests.sh
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
#!/bin/sh
|
2
|
-
|
3
|
-
echo "\033[1;81m Running test_timecop_internals...\033[0m"
|
4
|
-
ruby test_timecop_internals.rb || (echo "FAILED!!!!!!!!!!!!")
|
5
|
-
|
6
|
-
echo "\033[1;81m Running test_timecop_without_date...\033[0m"
|
7
|
-
ruby test_timecop_without_date.rb || (echo "FAILED!!!!!!!!!!!!")
|
8
|
-
|
9
|
-
echo "\033[1;81m Running test_timecop...\033[0m"
|
10
|
-
ruby test_timecop.rb || (echo "FAILED!!!!!!!!!!!!")
|
@@ -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
|