timecop 0.5.1 → 0.5.2

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.rdoc CHANGED
@@ -1,3 +1,8 @@
1
+ === 0.5.2 / 2012-09-20
2
+
3
+ * Feature
4
+ * Timecop#scale, ability to accelerate time by a given scaling factor
5
+
1
6
  === 0.5.0 / 2012-09-12
2
7
 
3
8
  * Maintenance
data/README.markdown CHANGED
@@ -15,6 +15,7 @@ A gem providing "time travel" and "time freezing" capabilities, making it dead s
15
15
 
16
16
  - Freeze time to a specific point.
17
17
  - Travel back to a specific point in time, but allow time to continue moving forward from there.
18
+ - Scale time by a given scaling factor that will cause time to move at an accelerated pace.
18
19
  - No dependencies, can be used with _any_ ruby project
19
20
  - Timecop api allows arguments to be passed into #freeze and #travel as one of the following:
20
21
  - Time instance
@@ -75,6 +76,23 @@ sleep(10)
75
76
  new_time == Time.now # ==> false
76
77
  ```
77
78
 
79
+ ### Timecop.scale
80
+
81
+ Let's say you want to test a "live" integration wherein entire days could pass by
82
+ in minutes while you're able to simulate "real" activity. For example, one such use case
83
+ is being able to test reports and invoices that run in 30 day cycles in very little time, while also
84
+ being able to simulate activity via subsequent calls to your application.
85
+
86
+ ```ruby
87
+ # seconds will now seem like hours
88
+ Timecop.lens(3600)
89
+ Time.now
90
+ # => 2012-09-20 21:23:25 -0500
91
+ # seconds later, hours have past it's gone from 9pm at night to 6am in the morning
92
+ Time.now
93
+ # => 2012-09-21 06:22:59 -0500
94
+ ```
95
+
78
96
  ## REFERENCES
79
97
 
80
98
  * {0.3.4 release}[http://blog.smartlogicsolutions.com/2009/12/07/timecop-0-3-4-released/]
@@ -6,9 +6,11 @@ class Timecop
6
6
 
7
7
  attr_reader :mock_type
8
8
  def initialize(mock_type, *args)
9
- raise "Unknown mock_type #{mock_type}" unless [:freeze, :travel].include?(mock_type)
9
+ raise "Unknown mock_type #{mock_type}" unless [:freeze, :travel, :scale].include?(mock_type)
10
+ @scaling_factor = args.shift if mock_type == :scale
10
11
  @mock_type = mock_type
11
12
  @time = parse_time(*args)
13
+ @time_was = Time.now_without_mock_time
12
14
  @travel_offset = compute_travel_offset
13
15
  @dst_adjustment = compute_dst_adjustment(@time)
14
16
  end
@@ -44,14 +46,24 @@ class Timecop
44
46
  def travel_offset
45
47
  @travel_offset
46
48
  end
49
+
50
+ def scaling_factor
51
+ @scaling_factor
52
+ end
47
53
 
48
54
  def time(time_klass=Time) #:nodoc:
49
55
  if travel_offset.nil?
50
56
  time_klass.at( @time.to_f )
51
- else
57
+ elsif scaling_factor.nil?
52
58
  time_klass.at( ( Time.now_without_mock_time + travel_offset ).to_f )
59
+ else
60
+ time_klass.at( scaled_time )
53
61
  end
54
62
  end
63
+
64
+ def scaled_time
65
+ (@time + (Time.now_without_mock_time - @time_was) * scaling_factor).to_f
66
+ end
55
67
 
56
68
  def date(date_klass=Date)
57
69
  date_klass.jd(time.__send__(:to_date).jd)
@@ -67,6 +67,20 @@ class Timecop
67
67
  block_given? ? val : nil
68
68
  end
69
69
 
70
+ # Allows you to run a block of code and "scale" a time throughout the execution of that block.
71
+ # The first argument is a scaling factor, for example:
72
+ # Timecop.scale(2) do
73
+ # ... time will 'go' twice as fast here
74
+ # end
75
+ # See Timecop#freeze for exact usage of the other arguments
76
+ #
77
+ # Returns the value of the block or nil.
78
+ def scale(*args, &block)
79
+ val = instance().send(:travel, :scale, *args, &block)
80
+
81
+ block_given? ? val : nil
82
+ end
83
+
70
84
  def baseline
71
85
  instance().send(:baseline)
72
86
  end
@@ -1,3 +1,3 @@
1
1
  class Timecop
2
- VERSION = "0.5.1"
2
+ VERSION = "0.5.2"
3
3
  end
@@ -172,6 +172,15 @@ class TestTimeStackItem < Test::Unit::TestCase
172
172
  assert_equal nil, tsi.send(:travel_offset)
173
173
  end
174
174
 
175
+ def test_set_scaling_factor_for_lens
176
+ t_now = Time.now
177
+ t = Time.local(2009, 10, 1, 0, 0, 30)
178
+ expected_offset = t - t_now
179
+ tsi = Timecop::TimeStackItem.new(:scale, 4, t)
180
+ assert_times_effectively_equal expected_offset, tsi.send(:travel_offset), 1, "Offset not calculated correctly"
181
+ assert_equal tsi.send(:scaling_factor), 4, "Scaling factor not set"
182
+ end
183
+
175
184
  def test_parse_string_date_with_active_support
176
185
  date = '2012-01-02'
177
186
  Time.expects(:parse).with(date).returns(Time.local(2012, 01, 02))
data/test/timecop_test.rb CHANGED
@@ -250,6 +250,16 @@ class TestTimecop < Test::Unit::TestCase
250
250
  end
251
251
  end
252
252
 
253
+ def test_lensing_keeps_time_moving_at_an_accelerated_rate
254
+ t = Time.local(2008, 10, 10, 10, 10, 10)
255
+ Timecop.scale(4, t) do
256
+ start = Time.now
257
+ assert_times_effectively_equal start, t, 1, "Looks like we failed to actually travel time"
258
+ sleep(0.25)
259
+ assert_times_effectively_equal Time.at((start + 4*0.25).to_f), Time.now, 0.25, "Looks like time is not moving at 4x"
260
+ end
261
+ end
262
+
253
263
  def test_freeze_with_utc_time
254
264
  each_timezone do
255
265
  t = Time.utc(2008, 10, 10, 10, 10, 10)
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.5.1
4
+ version: 0.5.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-09-05 00:00:00.000000000 Z
13
+ date: 2012-09-20 00:00:00.000000000 Z
14
14
  dependencies: []
15
15
  description: A gem providing "time travel" and "time freezing" capabilities, making
16
16
  it dead simple to test time-dependent code. It provides a unified method to mock
@@ -50,6 +50,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
50
50
  - - ! '>='
51
51
  - !ruby/object:Gem::Version
52
52
  version: '0'
53
+ segments:
54
+ - 0
55
+ hash: -1525074573276164628
53
56
  required_rubygems_version: !ruby/object:Gem::Requirement
54
57
  none: false
55
58
  requirements: