timespan 0.5.5 → 0.5.6
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/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:
|