time_freeze 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/lib/time_freeze/time_extensions.rb +43 -0
- data/lib/time_freeze.rb +62 -0
- data/test/test_helper.rb +5 -0
- data/test/time_freeze_test.rb +95 -0
- metadata +70 -0
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
class Time
|
4
|
+
|
5
|
+
# stolen from ActiveSupport...
|
6
|
+
# but I don't want to require ActiveSupport
|
7
|
+
|
8
|
+
# Converts a Time object to a Date, dropping hour, minute, and second precision.
|
9
|
+
#
|
10
|
+
# my_time = Time.now # => Mon Nov 12 22:59:51 -0500 2007
|
11
|
+
# my_time.to_date # => Mon, 12 Nov 2007
|
12
|
+
#
|
13
|
+
# your_time = Time.parse("1/13/2009 1:13:03 P.M.") # => Tue Jan 13 13:13:03 -0500 2009
|
14
|
+
# your_time.to_date # => Tue, 13 Jan 2009
|
15
|
+
def to_date
|
16
|
+
::Date.new(year, month, day)
|
17
|
+
end unless method_defined?(:to_date)
|
18
|
+
|
19
|
+
# A method to keep Time, Date and DateTime instances interchangeable on conversions.
|
20
|
+
# In this case, it simply returns +self+.
|
21
|
+
def to_time
|
22
|
+
self
|
23
|
+
end unless method_defined?(:to_time)
|
24
|
+
|
25
|
+
# Converts a Time instance to a Ruby DateTime instance, preserving UTC offset.
|
26
|
+
#
|
27
|
+
# my_time = Time.now # => Mon Nov 12 23:04:21 -0500 2007
|
28
|
+
# my_time.to_datetime # => Mon, 12 Nov 2007 23:04:21 -0500
|
29
|
+
#
|
30
|
+
# your_time = Time.parse("1/13/2009 1:13:03 P.M.") # => Tue Jan 13 13:13:03 -0500 2009
|
31
|
+
# your_time.to_datetime # => Tue, 13 Jan 2009 13:13:03 -0500
|
32
|
+
def to_datetime
|
33
|
+
::DateTime.civil(year, month, day, hour, min, sec, Rational(utc_offset, 86400))
|
34
|
+
end unless method_defined?(:to_datetime)
|
35
|
+
|
36
|
+
# Ruby 1.8-cvs and early 1.9 series define private Time#to_date
|
37
|
+
%w(to_time to_date to_datetime).each do |method|
|
38
|
+
if private_instance_methods.include?(method) || private_instance_methods.include?(method.to_sym)
|
39
|
+
public method
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
data/lib/time_freeze.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'time_freeze/time_extensions'
|
2
|
+
|
3
|
+
module TimeFreeze
|
4
|
+
|
5
|
+
@@frozen_time = nil
|
6
|
+
|
7
|
+
def self.frozen_time
|
8
|
+
@@frozen_time
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.frozen_time=(value)
|
12
|
+
@@frozen_time = value
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.freeze!(frozen_time=Time.now)
|
16
|
+
raise ArgumentError, "we can only freeze to a Time" unless frozen_time.is_a?(Time)
|
17
|
+
TimeFreeze.frozen_time, time_before = frozen_time, TimeFreeze.frozen_time
|
18
|
+
yield
|
19
|
+
ensure
|
20
|
+
# no matter what happens
|
21
|
+
# we need to reset this
|
22
|
+
TimeFreeze.frozen_time = time_before
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.unfreeze!
|
26
|
+
self.frozen_time=nil
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
class << Time
|
32
|
+
alias :now_unfrozen :now
|
33
|
+
def now
|
34
|
+
if TimeFreeze.frozen_time
|
35
|
+
TimeFreeze.frozen_time.to_time
|
36
|
+
else
|
37
|
+
self.now_unfrozen
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class << Date
|
43
|
+
alias :today_unfrozen :today
|
44
|
+
def today
|
45
|
+
if TimeFreeze.frozen_time
|
46
|
+
TimeFreeze.frozen_time.to_date
|
47
|
+
else
|
48
|
+
self.today_unfrozen
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class << DateTime
|
54
|
+
alias :now_unfrozen :now
|
55
|
+
def now
|
56
|
+
if TimeFreeze.frozen_time
|
57
|
+
TimeFreeze.frozen_time.to_datetime
|
58
|
+
else
|
59
|
+
self.now_unfrozen
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'time'
|
3
|
+
require 'date'
|
4
|
+
|
5
|
+
class TimeFreezeTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@time_now = Time.now
|
9
|
+
@datetime_now = DateTime.now
|
10
|
+
@date_today = Date.today
|
11
|
+
|
12
|
+
TimeFreeze.unfreeze!
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_normal_function
|
16
|
+
assert_unfrozen_time
|
17
|
+
|
18
|
+
sleep 10
|
19
|
+
|
20
|
+
assert_unfrozen_time(10)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_freeze!
|
24
|
+
time1 = Time.mktime(2001,12,30,13,45,59,999999)
|
25
|
+
|
26
|
+
assert_unfrozen_time
|
27
|
+
|
28
|
+
TimeFreeze.freeze!(time1) do
|
29
|
+
assert_frozen_time(time1)
|
30
|
+
end
|
31
|
+
|
32
|
+
assert_unfrozen_time
|
33
|
+
end
|
34
|
+
|
35
|
+
class ExampleRaisedException < Exception; end
|
36
|
+
|
37
|
+
def test_freeze_unfreezes_after_exception
|
38
|
+
time1 = Time.mktime(2001,12,30,13,45,59,999999)
|
39
|
+
|
40
|
+
assert_unfrozen_time
|
41
|
+
|
42
|
+
begin
|
43
|
+
TimeFreeze.freeze!(time1) do
|
44
|
+
|
45
|
+
assert_frozen_time(time1)
|
46
|
+
|
47
|
+
raise ExampleRaisedException
|
48
|
+
|
49
|
+
flunk "we seem to have resumed after the raise"
|
50
|
+
end
|
51
|
+
|
52
|
+
rescue ExampleRaisedException
|
53
|
+
|
54
|
+
assert_unfrozen_time
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
assert_unfrozen_time
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_nested_freeze
|
62
|
+
time1 = Time.mktime(2001,12,30,13,45,59,999999)
|
63
|
+
time2 = Time.mktime(2015,03,16,23,22,13,764282)
|
64
|
+
|
65
|
+
assert_unfrozen_time
|
66
|
+
|
67
|
+
TimeFreeze.freeze!(time1) do
|
68
|
+
assert_frozen_time(time1)
|
69
|
+
|
70
|
+
TimeFreeze.freeze!(time2) do
|
71
|
+
assert_frozen_time(time2)
|
72
|
+
end
|
73
|
+
|
74
|
+
assert_frozen_time(time1)
|
75
|
+
end
|
76
|
+
|
77
|
+
assert_unfrozen_time
|
78
|
+
end
|
79
|
+
|
80
|
+
def assert_frozen_time(expected_time)
|
81
|
+
assert_equal TimeFreeze.frozen_time, expected_time
|
82
|
+
assert_equal expected_time, Time.now
|
83
|
+
assert_equal expected_time.to_datetime, DateTime.now
|
84
|
+
assert_equal expected_time.to_date, Date.today
|
85
|
+
end
|
86
|
+
|
87
|
+
def assert_unfrozen_time(offset=0)
|
88
|
+
assert_in_delta offset, Time.now - @time_now, 0.5
|
89
|
+
assert_in_delta offset*DateTime::SECONDS_IN_DAY, DateTime.now - @datetime_now, 0.5*DateTime::SECONDS_IN_DAY
|
90
|
+
|
91
|
+
assert_equal @date_today, Date.today
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: time_freeze
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Matthew Rudy Jacobs
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-12-02 00:00:00 +08:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description:
|
23
|
+
email: MatthewRudyJacobs@gmail.com
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files: []
|
29
|
+
|
30
|
+
files:
|
31
|
+
- test/test_helper.rb
|
32
|
+
- test/time_freeze_test.rb
|
33
|
+
- lib/time_freeze/time_extensions.rb
|
34
|
+
- lib/time_freeze.rb
|
35
|
+
has_rdoc: true
|
36
|
+
homepage: http://yoursite.example.com
|
37
|
+
licenses: []
|
38
|
+
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options: []
|
41
|
+
|
42
|
+
require_paths:
|
43
|
+
- lib
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
none: false
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
hash: 3
|
50
|
+
segments:
|
51
|
+
- 0
|
52
|
+
version: "0"
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
hash: 3
|
59
|
+
segments:
|
60
|
+
- 0
|
61
|
+
version: "0"
|
62
|
+
requirements: []
|
63
|
+
|
64
|
+
rubyforge_project:
|
65
|
+
rubygems_version: 1.3.7
|
66
|
+
signing_key:
|
67
|
+
specification_version: 3
|
68
|
+
summary: The simplest possible way to freeze time
|
69
|
+
test_files: []
|
70
|
+
|