timespan 0.5.5 → 0.5.6
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +7 -0
- data/VERSION +1 -1
- data/lib/timespan/core_ext/hash.rb +11 -1
- data/lib/timespan/core_ext/range.rb +69 -8
- data/spec/timespan/core_ext/duration_range_spec.rb +20 -16
- data/spec/timespan/mongoid/mongoid_duration_range_spec.rb +123 -17
- data/timespan.gemspec +1 -1
- metadata +2 -2
data/README.md
CHANGED
@@ -324,6 +324,13 @@ dr.between?(4.days) # => true
|
|
324
324
|
|
325
325
|
You can also use Range#intersect from *sugar-high* gem to test intersection of time ranges ;)
|
326
326
|
|
327
|
+
See https://github.com/kristianmandrup/sugar-high/blob/master/spec/sugar-high/range_spec.rb
|
328
|
+
|
329
|
+
```ruby
|
330
|
+
date_range.intersect(other_date_range).should == intersecting_range
|
331
|
+
subject.intersect(other).should == nil # if no intersection
|
332
|
+
```
|
333
|
+
|
327
334
|
The duration range by default supports the following units: [seconds, minutes, hours, days, weeks, months, years]
|
328
335
|
|
329
336
|
You can subclass the DurationRange to supply your own list of time units to fit your particular scenario.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.5.
|
1
|
+
0.5.6
|
@@ -8,6 +8,16 @@ class Hash
|
|
8
8
|
|
9
9
|
def __evolve_to_duration_range__
|
10
10
|
range = Range.new (self['from'] || self[:from]), (self['to'] || self[:to])
|
11
|
-
|
11
|
+
length = self['length'] || self[:length]
|
12
|
+
clazz = case length.to_sym
|
13
|
+
when :long
|
14
|
+
::LongDurationRange
|
15
|
+
when :short
|
16
|
+
::ShortDurationRange
|
17
|
+
else
|
18
|
+
::DurationRange
|
19
|
+
end
|
20
|
+
|
21
|
+
clazz.new range, (self['unit'] || self[:unit] || :seconds)
|
12
22
|
end
|
13
23
|
end
|
@@ -18,6 +18,8 @@ class TimespanRange < DelegateDecorator
|
|
18
18
|
end
|
19
19
|
|
20
20
|
class DurationRange < DelegateDecorator
|
21
|
+
include Comparable
|
22
|
+
|
21
23
|
attr_accessor :unit, :range
|
22
24
|
|
23
25
|
def initialize range, unit = :minutes
|
@@ -34,6 +36,30 @@ class DurationRange < DelegateDecorator
|
|
34
36
|
@range = range
|
35
37
|
end
|
36
38
|
|
39
|
+
alias_method :units, :unit
|
40
|
+
|
41
|
+
def <=> other_dur_range
|
42
|
+
min_secs = self.min
|
43
|
+
max_secs = self.max
|
44
|
+
omin_secs = other_dur_range.min
|
45
|
+
omax_secs = other_dur_range.max
|
46
|
+
|
47
|
+
# puts "self: #{self.inspect} vs #{other_dur_range.inspect} #{other_dur_range.class}"
|
48
|
+
|
49
|
+
if min_secs == omin_secs && max_secs == omax_secs
|
50
|
+
return 0
|
51
|
+
end
|
52
|
+
|
53
|
+
if min_secs < omin_secs || (min_secs == omin_secs && max_secs < omax_secs)
|
54
|
+
-1
|
55
|
+
else
|
56
|
+
1
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def length
|
61
|
+
:default
|
62
|
+
end
|
37
63
|
|
38
64
|
def self.allowed_unit? unit
|
39
65
|
allowed_units.include? unit.to_sym
|
@@ -55,12 +81,8 @@ class DurationRange < DelegateDecorator
|
|
55
81
|
range.min.nil? ? 'no duration range' : "#{range.min} to #{range.max} #{unit}"
|
56
82
|
end
|
57
83
|
|
58
|
-
def
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
|
-
def mongoize
|
63
|
-
{:from => range.min.to_i, :to => range.max.to_i}
|
84
|
+
def time
|
85
|
+
"#{min + max} #{unit}"
|
64
86
|
end
|
65
87
|
|
66
88
|
def between? duration
|
@@ -73,6 +95,20 @@ class DurationRange < DelegateDecorator
|
|
73
95
|
obj.total >= min && obj.total <= max
|
74
96
|
end
|
75
97
|
|
98
|
+
def to_hash
|
99
|
+
{:from => range.min.to_i, :to => range.max.to_i, unit: unit.to_s, length: length.to_s}
|
100
|
+
end
|
101
|
+
|
102
|
+
def mongoize
|
103
|
+
to_hash
|
104
|
+
end
|
105
|
+
|
106
|
+
protected
|
107
|
+
|
108
|
+
def __evolve_to_duration_range__
|
109
|
+
self
|
110
|
+
end
|
111
|
+
|
76
112
|
class << self
|
77
113
|
# See http://mongoid.org/en/mongoid/docs/upgrading.html
|
78
114
|
|
@@ -105,6 +141,8 @@ class DurationRange < DelegateDecorator
|
|
105
141
|
demongoized = case object
|
106
142
|
when Hash
|
107
143
|
object.__evolve_to_duration_range__
|
144
|
+
when Range
|
145
|
+
object.__evolve_to_duration_range__
|
108
146
|
else
|
109
147
|
raise "Unable to demongoize DurationRange from: #{object}"
|
110
148
|
end
|
@@ -146,6 +184,16 @@ class DurationRange < DelegateDecorator
|
|
146
184
|
end
|
147
185
|
|
148
186
|
class LongDurationRange < DurationRange
|
187
|
+
# include Comparable
|
188
|
+
|
189
|
+
# def <=> other_dur_range
|
190
|
+
# super
|
191
|
+
# end
|
192
|
+
|
193
|
+
def length
|
194
|
+
:long
|
195
|
+
end
|
196
|
+
|
149
197
|
def self.allowed_units
|
150
198
|
[:days, :weeks, :months, :years]
|
151
199
|
end
|
@@ -156,6 +204,16 @@ class LongDurationRange < DurationRange
|
|
156
204
|
end
|
157
205
|
|
158
206
|
class ShortDurationRange < DurationRange
|
207
|
+
# include Comparable
|
208
|
+
|
209
|
+
# def <=> other_dur_range
|
210
|
+
# super
|
211
|
+
# end
|
212
|
+
|
213
|
+
def length
|
214
|
+
:short
|
215
|
+
end
|
216
|
+
|
159
217
|
def self.allowed_units
|
160
218
|
[:seconds, :minutes, :hours]
|
161
219
|
end
|
@@ -163,10 +221,13 @@ class ShortDurationRange < DurationRange
|
|
163
221
|
def allowed_units
|
164
222
|
ShortDurationRange.allowed_units
|
165
223
|
end
|
166
|
-
end
|
167
|
-
|
224
|
+
end
|
168
225
|
|
169
226
|
class Range
|
227
|
+
def __evolve_to_duration_range__
|
228
|
+
::DurationRange.new self, :seconds
|
229
|
+
end
|
230
|
+
|
170
231
|
[:seconds, :minutes, :hours, :days, :weeks, :months, :years].each do |unit|
|
171
232
|
define_method "#{unit}!" do
|
172
233
|
time_length = ::ShortDurationRange.allowed_unit?(unit.to_sym) ? :short : :long
|
@@ -4,52 +4,56 @@ describe Range do
|
|
4
4
|
subject { timerange }
|
5
5
|
|
6
6
|
describe 'create DurationRange' do
|
7
|
-
let(:range)
|
8
|
-
let (:timerange)
|
7
|
+
let(:range) { (1..5) }
|
8
|
+
let (:timerange) { range.days }
|
9
9
|
|
10
10
|
specify { subject.should be_a DurationRange }
|
11
11
|
|
12
|
-
its(:min)
|
13
|
-
its(:max)
|
12
|
+
its(:min) { should be_a Fixnum }
|
13
|
+
its(:max) { should be_a Fixnum }
|
14
|
+
its(:unit) { should == :days }
|
14
15
|
|
15
16
|
specify { subject.min.should == 1.day }
|
16
17
|
specify { subject.max.should == 5.days }
|
17
18
|
end
|
18
19
|
|
19
20
|
describe 'create ShortDurationRange with hours(:short)' do
|
20
|
-
let(:range)
|
21
|
-
let (:timerange)
|
21
|
+
let(:range) { (1..5) }
|
22
|
+
let (:timerange) { range.hours(:short) }
|
22
23
|
|
23
24
|
specify { subject.should be_a ShortDurationRange }
|
24
25
|
|
25
|
-
its(:min)
|
26
|
-
its(:max)
|
26
|
+
its(:min) { should be_a Fixnum }
|
27
|
+
its(:max) { should be_a Fixnum }
|
28
|
+
its(:unit) { should == :hours }
|
27
29
|
|
28
30
|
specify { subject.min.should == 1.hour }
|
29
31
|
specify { subject.max.should == 5.hours }
|
30
32
|
end
|
31
33
|
|
32
34
|
describe 'create LongDurationRange with weeks(:long)' do
|
33
|
-
let(:range)
|
34
|
-
let (:timerange)
|
35
|
+
let(:range) { (1..5) }
|
36
|
+
let (:timerange) { range.weeks(:long) }
|
35
37
|
|
36
38
|
specify { subject.should be_a LongDurationRange }
|
37
39
|
|
38
|
-
its(:min)
|
39
|
-
its(:max)
|
40
|
+
its(:min) { should be_a Fixnum }
|
41
|
+
its(:max) { should be_a Fixnum }
|
42
|
+
its(:unit) { should == :weeks }
|
40
43
|
|
41
44
|
specify { subject.min.should == 1.weeks }
|
42
45
|
specify { subject.max.should == 5.weeks }
|
43
46
|
end
|
44
47
|
|
45
48
|
describe 'create LongDurationRange with weeks!' do
|
46
|
-
let(:range)
|
47
|
-
let (:timerange)
|
49
|
+
let(:range) { (1..5) }
|
50
|
+
let (:timerange) { range.weeks! }
|
48
51
|
|
49
52
|
specify { subject.should be_a LongDurationRange }
|
50
53
|
|
51
|
-
its(:min)
|
52
|
-
its(:max)
|
54
|
+
its(:min) { should be_a Fixnum }
|
55
|
+
its(:max) { should be_a Fixnum }
|
56
|
+
its(:unit) { should == :weeks }
|
53
57
|
|
54
58
|
specify { subject.min.should == 1.weeks }
|
55
59
|
specify { subject.max.should == 5.weeks }
|
@@ -18,33 +18,139 @@ describe TimeSpan do
|
|
18
18
|
let(:to) { Time.now }
|
19
19
|
|
20
20
|
context 'Mongoid' do
|
21
|
-
describe 'DurationRange'
|
21
|
+
describe 'DurationRange' do
|
22
22
|
|
23
|
-
|
24
|
-
|
23
|
+
let(:account) do
|
24
|
+
Account.create_it! 2.days, (0..3).minutes
|
25
|
+
end
|
26
|
+
|
27
|
+
# subject.time_period.dates_end = tomorrow + 3.days
|
28
|
+
# subject.end_date = tomorrow + 3.days
|
29
|
+
|
30
|
+
context 'set start of period to tomorrow' do
|
31
|
+
before do
|
32
|
+
subject.period_start = tomorrow
|
33
|
+
|
34
|
+
puts "period: #{subject.period}"
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should set start_date to tomorrow' do
|
38
|
+
format_date(subject.period.start_date).should == format_date(tomorrow)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'set end of period to tomorrow + 5 days' do
|
43
|
+
before do
|
44
|
+
subject.period_end = tomorrow + 5.days
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should set start_date to tomorrow' do
|
48
|
+
format_date(subject.period.end_date).should == format_date(tomorrow + 5.days)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'set flex to 1-3 days' do
|
53
|
+
before do
|
54
|
+
subject.time_period.flex = (1..3).days
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should set flex duration range to a DurationRange' do
|
58
|
+
expect(subject.time_period.flex).to be_a ::DurationRange
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should set flex duration range to days' do
|
62
|
+
expect(subject.time_period.flex.unit).to eq :days
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should set flex duration to min 1 days' do
|
66
|
+
expect(subject.time_period.flex.min).to eq 1.days
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should set flex duration to max 3 days' do
|
70
|
+
expect(subject.time_period.flex.max).to eq 3.days
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe 'LongDurationRange' do
|
76
|
+
let(:account) do
|
77
|
+
Account.create_it! 2.days
|
78
|
+
end
|
79
|
+
|
80
|
+
before do
|
81
|
+
subject.time_period.flex = (2..3).weeks!
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should set flex duration range to a LongDurationRange' do
|
85
|
+
expect(subject.time_period.flex).to be_a ::LongDurationRange
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'should set flex duration range to 2-3 weeks' do
|
89
|
+
expect(subject.time_period.flex.unit).to eq :weeks
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'should set flex duration to min 2 week' do
|
93
|
+
expect(subject.time_period.flex.min).to eq 2.weeks
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should set flex duration to max 3 weeks' do
|
97
|
+
expect(subject.time_period.flex.max).to eq 3.weeks
|
98
|
+
end
|
25
99
|
end
|
26
100
|
|
27
|
-
describe '
|
101
|
+
describe 'ShortDurationRange' do
|
102
|
+
context 'preset to 2-4 days' do
|
103
|
+
let(:account) do
|
104
|
+
Account.create_it! 2.days, (2..4).days!
|
105
|
+
end
|
106
|
+
|
107
|
+
specify do
|
108
|
+
((2..5).days! == (2..4).days!).should be_false
|
109
|
+
end
|
110
|
+
|
111
|
+
specify do
|
112
|
+
((2..5).days! > (2..4).days!).should be_true
|
113
|
+
end
|
114
|
+
|
115
|
+
specify do
|
116
|
+
((1..3).days! < (2..4).days!).should be_true
|
117
|
+
end
|
118
|
+
|
119
|
+
specify do
|
120
|
+
subject.time_period.flex.should be_a ::LongDurationRange
|
121
|
+
end
|
28
122
|
|
29
|
-
|
30
|
-
|
31
|
-
|
123
|
+
it 'should be set to 2-4 days time' do
|
124
|
+
expect(subject.time_period.flex.time).to eq (2..4).days!.time
|
125
|
+
end
|
32
126
|
|
33
|
-
|
34
|
-
|
127
|
+
it 'should be set to 2-4 days' do
|
128
|
+
expect(subject.time_period.flex.to_s).to eq (2..4).days!.to_s
|
129
|
+
end
|
35
130
|
|
36
|
-
|
131
|
+
it 'should be set to min 2 days' do
|
132
|
+
expect(subject.time_period.flex.min).to eq 2.days
|
133
|
+
end
|
37
134
|
|
135
|
+
it 'should be set to max 4 days' do
|
136
|
+
expect(subject.time_period.flex.max).to eq 4.days
|
137
|
+
end
|
38
138
|
|
39
|
-
|
40
|
-
|
41
|
-
|
139
|
+
context 'set to 1-4 minutes' do
|
140
|
+
before do
|
141
|
+
subject.time_period.flex = (2..3).minutes!
|
142
|
+
end
|
42
143
|
|
43
|
-
|
44
|
-
|
45
|
-
|
144
|
+
it 'should set flex duration range to a LongDurationRange' do
|
145
|
+
expect(subject.time_period.flex).to be_a ::ShortDurationRange
|
146
|
+
end
|
46
147
|
|
47
|
-
|
148
|
+
it 'should set flex duration range to 2-3 minutes' do
|
149
|
+
expect(subject.time_period.flex.unit).to eq :minutes
|
150
|
+
expect(subject.time_period.flex.min).to eq 2.minutes
|
151
|
+
expect(subject.time_period.flex.max).to eq 3.minutes
|
152
|
+
end
|
153
|
+
end
|
48
154
|
end
|
49
155
|
end
|
50
156
|
end
|
data/timespan.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: timespan
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -293,7 +293,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
293
293
|
version: '0'
|
294
294
|
segments:
|
295
295
|
- 0
|
296
|
-
hash: -
|
296
|
+
hash: -3092894469197231264
|
297
297
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
298
298
|
none: false
|
299
299
|
requirements:
|