timerage 2.0.0 → 2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f82bbd7083065080ca7d80bf905a6f77d8bf2e7f
4
- data.tar.gz: fbbcc51556bbdcf68e000937cb0d219c78f942e1
3
+ metadata.gz: 852f05909b0c54b53238eeccad669f7f71afcfd9
4
+ data.tar.gz: 991234a087b2d382acb900a2869557f764e50d7a
5
5
  SHA512:
6
- metadata.gz: 0f3d81194d057830e4fe1743df1b8fe65c79af78ebf71f406792d1d26f513aac2f42321dea5cc58633c9733aa043321b091f96e6fc6244d99952b9bc81c8ea66
7
- data.tar.gz: 04d3101baf65ab9eef0b4ffd3ccd7b6081016debe211e69cdf40c7f26395809f2efb29e66fbd785cbb94749da93fb5d2ae7a8cdcd9ec79f67b6865a1f9edb3d2
6
+ metadata.gz: e05d511d2ecec9629e85a8d3db2c5b7e251d084a289f159e1d07843098a398cf46f74cb197c23197c2a3b2748331586f678b1d7810c13aeb3fd5b33fabeea14c
7
+ data.tar.gz: 8111ba63bf032f12969d21260ad89c9ce1d3ec94139863531ca0bc8811eb0d83c37d7ad8cef1e362edb6ef14253db702fe025cd950adba674c026b7d1d3349ef
@@ -2,15 +2,15 @@ require "delegate"
2
2
 
3
3
  module Timerage
4
4
  # A range of time. The exposes the Range like interface.
5
- class TimeInterval < DelegateClass(Range)
6
- def initialize(*args)
7
- rng = if rangeish?(args.first)
8
- args.first
9
- else
10
- Range.new(*args)
11
- end
12
-
13
- super rng
5
+ class TimeInterval < Range
6
+
7
+ class << self
8
+ def new(*args)
9
+ args = [args.first.begin, args.first.end, args.first.exclude_end?] if args.first.respond_to?(:exclude_end?)
10
+ new_obj = allocate
11
+ new_obj.send(:initialize, *args)
12
+ new_obj
13
+ end
14
14
  end
15
15
 
16
16
  def to_time_interval
@@ -81,11 +81,11 @@ module Timerage
81
81
  end
82
82
 
83
83
  def overlap?(other)
84
- earliest, latest = if self.begin <= other.begin
85
- [self, other]
86
- else
87
- [other, self]
88
- end
84
+ if self.begin <= other.begin
85
+ earliest, latest = self, other
86
+ else
87
+ earliest, latest = other, self
88
+ end
89
89
 
90
90
  latest_begin, earliest_end = latest.begin, earliest.end
91
91
  return true if latest_begin < earliest_end
@@ -134,26 +134,14 @@ module Timerage
134
134
  an_obj.respond_to?(:end)
135
135
  end
136
136
 
137
- # ---
138
- #
139
- # This is implemented in a slightly more procedural style than i
140
- # prefer because we want to work well with ActiveSupport::Duration
141
- # steps. Adding a Duration to a time uses the timezone (dst, etc),
142
- # leap second and leap day aware `#advance` method in
143
- # ActiveSupport. However, multiplying a Duration by a number
144
- # returns a number, rather than a duration. This, in turn, means
145
- # that adding a duration times a number to a time results in
146
- # Timely incorrect results. So we do it the hard way.
147
137
  def time_enumerator(step)
148
138
  count = (self.end - self.begin).div(step) + 1
149
139
  count -= 1 if exclude_end? and (self.end - self.begin) % step == 0
150
140
  # We've included our end if it should be
151
141
 
152
142
  Enumerator.new do |y|
153
- y << last = self.begin
154
-
155
- (count-1).times do
156
- y << last = last + step
143
+ (count).times do |offset|
144
+ y << self.begin + (step * offset)
157
145
  end
158
146
  end
159
147
  end
@@ -1,3 +1,3 @@
1
1
  module Timerage
2
- VERSION = "2.0.0"
2
+ VERSION = "2.1.0"
3
3
  end
@@ -1,4 +1,5 @@
1
1
  require_relative "../spec_helper"
2
+ require "active_support/all"
2
3
 
3
4
  describe Timerage::TimeInterval do
4
5
  let(:now) { Time.now }
@@ -179,6 +180,41 @@ describe Timerage::TimeInterval do
179
180
  specify { expect( interval.duration).to eq duration }
180
181
  end
181
182
 
183
+ context "exclusive 0 length interval" do
184
+ subject(:interval) { described_class.new(now...now) }
185
+ specify { expect{ |b| subject.step(1, &b) }.not_to yield_control }
186
+ end
187
+
188
+ context "inclusive 0 length interval" do
189
+ subject(:interval) { described_class.new(now..now) }
190
+ specify { expect{ |b| subject.step(1, &b) }.to yield_control.once }
191
+ end
192
+
193
+ context "includes leap day" do
194
+ subject(:interval) { described_class.new(before_leap_day..after_leap_day) }
195
+ specify { expect{ |b| subject.step(1.day, &b) }.to yield_control.exactly(3).times }
196
+ specify { expect{ |b| subject.step(86_400, &b) }.to yield_control.exactly(3).times }
197
+ end
198
+
199
+ context "transition into dst with explicit time zone" do
200
+ subject(:interval) { described_class.new(before_dst..after_dst) }
201
+ specify { expect{ |b| subject.step(1.hour, &b) }.to yield_control.exactly(2).times }
202
+ specify { expect{ |b| subject.step(3_600, &b) }.to yield_control.exactly(2).times }
203
+ end
204
+
205
+ context "transition into dst without explicit time zone" do
206
+ subject(:interval) { described_class.new(before_dst..(before_dst + 1.hour)) }
207
+ specify { expect{ |b| subject.step(1.hour, &b) }.to yield_control.exactly(2).times }
208
+ specify { expect{ |b| subject.step(3_600, &b) }.to yield_control.exactly(2).times }
209
+ end
210
+
211
+ let(:leap_day) { Time.parse("2016-02-29 12:00:00 UTC") }
212
+ let(:before_leap_day) { leap_day - 1.day }
213
+ let(:after_leap_day) { leap_day + 1.day}
214
+
215
+ let(:before_dst) { Time.parse("2016-03-13 01:30:00 MST") }
216
+ let(:after_dst) { Time.parse("2016-03-13 03:30:00 MDT") }
217
+
182
218
  matcher :behave_like_a do |expected|
183
219
  match do |actual|
184
220
  Set[*expected.instance_methods].subset? Set[*actual.methods]
data/timerage.gemspec CHANGED
@@ -21,4 +21,5 @@ Gem::Specification.new do |spec|
21
21
  spec.add_development_dependency "bundler", "~> 1.5"
22
22
  spec.add_development_dependency "rake"
23
23
  spec.add_development_dependency "rspec", ["> 3.0.0.a", "< 4"]
24
+ spec.add_development_dependency "activesupport"
24
25
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timerage
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Williams
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-01-18 00:00:00.000000000 Z
12
+ date: 2016-02-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -59,6 +59,20 @@ dependencies:
59
59
  - - "<"
60
60
  - !ruby/object:Gem::Version
61
61
  version: '4'
62
+ - !ruby/object:Gem::Dependency
63
+ name: activesupport
64
+ requirement: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ type: :development
70
+ prerelease: false
71
+ version_requirements: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
62
76
  description: Simple refinement to Range to allow Time or Date as arguments
63
77
  email:
64
78
  - cschneider@comverge.com