duranged 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/duranged.rb +45 -0
- data/lib/duranged/base.rb +182 -0
- data/lib/duranged/duration.rb +6 -0
- data/lib/duranged/interval.rb +6 -0
- data/lib/duranged/occurrence.rb +124 -0
- data/lib/duranged/range.rb +111 -0
- data/lib/duranged/version.rb +3 -0
- data/spec/duranged/base_spec.rb +6 -0
- data/spec/duranged/duration_spec.rb +14 -0
- data/spec/duranged/interval_spec.rb +14 -0
- data/spec/duranged/occurrence_spec.rb +245 -0
- data/spec/duranged/range_spec.rb +324 -0
- data/spec/duranged_spec.rb +15 -0
- data/spec/shared/base_examples.rb +224 -0
- data/spec/spec_helper.rb +78 -0
- metadata +136 -0
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require File.join(File.dirname(__FILE__), '..', 'shared/base_examples.rb')
|
3
|
+
|
4
|
+
RSpec.describe Duranged::Duration do
|
5
|
+
it_behaves_like "the base class", Duranged::Duration
|
6
|
+
|
7
|
+
describe '#duration' do
|
8
|
+
subject { Duranged::Duration.new(30.seconds) }
|
9
|
+
|
10
|
+
it 'returns the duration value' do
|
11
|
+
expect(subject.duration).to eq(subject.value)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require File.join(File.dirname(__FILE__), '..', 'shared/base_examples.rb')
|
3
|
+
|
4
|
+
RSpec.describe Duranged::Interval do
|
5
|
+
it_behaves_like "the base class", Duranged::Interval
|
6
|
+
|
7
|
+
describe '#interval' do
|
8
|
+
subject { Duranged::Interval.new(30.seconds) }
|
9
|
+
|
10
|
+
it 'returns the interval value' do
|
11
|
+
expect(subject.interval).to eq(subject.value)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,245 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Duranged::Occurrence do
|
4
|
+
subject { Duranged::Occurrence.new(5, 36.hours) }
|
5
|
+
|
6
|
+
describe 'dump' do
|
7
|
+
it 'dumps the occurrence as a JSON hash' do
|
8
|
+
expect(Duranged::Occurrence.dump(subject)).to eq subject.to_json
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'load' do
|
13
|
+
context 'without a range' do
|
14
|
+
it 'creates a new occurrence from a JSON hash' do
|
15
|
+
expect(Duranged::Occurrence.load(subject.to_json)).to be_an_instance_of Duranged::Occurrence
|
16
|
+
expect(Duranged::Occurrence.load(subject.to_json).as_json).to eq subject.as_json
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'with a range' do
|
21
|
+
subject { Duranged::Occurrence.new(5, 36.hours, 10.minutes, Time.now, Time.now + 3.days) }
|
22
|
+
|
23
|
+
it 'creates a new occurrence from a JSON hash' do
|
24
|
+
expect(Duranged::Occurrence.load(subject.to_json)).to be_an_instance_of Duranged::Occurrence
|
25
|
+
expect(Duranged::Occurrence.load(subject.to_json).as_json).to eq subject.as_json
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#initialize' do
|
31
|
+
context 'with occurrences' do
|
32
|
+
it 'sets occurrences' do
|
33
|
+
expect(subject.occurrences).to eq 5
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'without occurrences' do
|
38
|
+
subject { Duranged::Occurrence.new }
|
39
|
+
|
40
|
+
it 'sets occurrences to 1' do
|
41
|
+
expect(subject.occurrences).to eq 1
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'with interval' do
|
46
|
+
it 'sets interval' do
|
47
|
+
expect(subject.interval).to eq 36.hours
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'without interval' do
|
52
|
+
subject { Duranged::Occurrence.new }
|
53
|
+
|
54
|
+
it 'sets interval to 0' do
|
55
|
+
expect(subject.interval).to eq nil
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'with duration' do
|
60
|
+
subject { Duranged::Occurrence.new(5, 36.hours, 20.minutes) }
|
61
|
+
|
62
|
+
it 'sets duration' do
|
63
|
+
expect(subject.duration).to eq 20.minutes
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'without duration' do
|
68
|
+
subject { Duranged::Occurrence.new }
|
69
|
+
|
70
|
+
it 'sets duration to 0' do
|
71
|
+
expect(subject.duration).to eq nil
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe '#occurrences_string' do
|
77
|
+
context 'with zero occurrences' do
|
78
|
+
subject { Duranged::Occurrence.new(0, 1.minute) }
|
79
|
+
|
80
|
+
it "returns 'never'" do
|
81
|
+
expect(subject.occurrences_string).to eq 'never'
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'with a single occurrence' do
|
86
|
+
subject { Duranged::Occurrence.new(1, 1.minute) }
|
87
|
+
|
88
|
+
it "returns 'once'" do
|
89
|
+
expect(subject.occurrences_string).to eq 'once'
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'with two occurrences' do
|
94
|
+
subject { Duranged::Occurrence.new(2, 1.minute) }
|
95
|
+
|
96
|
+
it "returns 'twice'" do
|
97
|
+
expect(subject.occurrences_string).to eq 'twice'
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'with multiple occurrences' do
|
102
|
+
subject { Duranged::Occurrence.new([3,4,5].sample, 1.minute) }
|
103
|
+
|
104
|
+
it "returns 'X times'" do
|
105
|
+
expect(subject.occurrences_string).to eq "#{subject.occurrences} times"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe '#as_json' do
|
111
|
+
context 'without a range' do
|
112
|
+
it 'returns an occurrences hash' do
|
113
|
+
expect(subject.as_json).to eq({occurrences: subject.occurrences, interval: subject.interval.as_json})
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'with a range' do
|
118
|
+
subject { Duranged::Occurrence.new(5, 36.hours, 10.minutes, Time.now, Time.now + 3.days) }
|
119
|
+
|
120
|
+
it 'returns an occurrences hash' do
|
121
|
+
expect(subject.as_json).to eq({occurrences: subject.occurrences, duration: subject.duration.as_json, interval: subject.interval.as_json, range: subject.range.as_json})
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe '#to_s' do
|
127
|
+
subject { Duranged::Occurrence.new(3, 1.day, 10.minutes) }
|
128
|
+
|
129
|
+
it "returns a string matching 'OCCURRENCES for DURATION every INTERVAL'" do
|
130
|
+
expect(subject.to_s).to eq "#{subject.occurrences_string} for #{subject.duration.to_s} every #{subject.interval.to_s}"
|
131
|
+
end
|
132
|
+
|
133
|
+
context 'when occurrences is 0' do
|
134
|
+
subject { Duranged::Occurrence.new(0, 30.seconds) }
|
135
|
+
|
136
|
+
it 'returns the occurrences_string' do
|
137
|
+
expect(subject.to_s).to eq subject.occurrences_string
|
138
|
+
end
|
139
|
+
|
140
|
+
it "returns 'never'" do
|
141
|
+
expect(subject.to_s).to eq 'never'
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
context 'when interval is 0' do
|
146
|
+
subject { Duranged::Occurrence.new(3, 0, 30.seconds) }
|
147
|
+
|
148
|
+
it "returns a string matching 'OCCURRENCES for DURATION'" do
|
149
|
+
expect(subject.to_s).to eq "#{subject.occurrences_string} for #{subject.duration.to_s}"
|
150
|
+
end
|
151
|
+
|
152
|
+
context 'when duration is 0' do
|
153
|
+
subject { Duranged::Occurrence.new(3) }
|
154
|
+
|
155
|
+
it 'returns the occurrences string' do
|
156
|
+
expect(subject.to_s).to eq subject.occurrences_string
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context 'when duration is 0' do
|
162
|
+
subject { Duranged::Occurrence.new(3, 1.day) }
|
163
|
+
|
164
|
+
it "returns a string matching 'OCCURRENCES every INTERVAL'" do
|
165
|
+
expect(subject.to_s).to eq "#{subject.occurrences_string} every #{subject.interval.to_s}"
|
166
|
+
end
|
167
|
+
|
168
|
+
context 'when interval is 0' do
|
169
|
+
subject { Duranged::Occurrence.new(3) }
|
170
|
+
|
171
|
+
it 'returns the occurrences string' do
|
172
|
+
expect(subject.to_s).to eq subject.occurrences_string
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe '#strfocc' do
|
179
|
+
context 'using the :occurence token' do
|
180
|
+
it 'returns the formatted string' do
|
181
|
+
expect(subject.strfocc(':occurrence')).to eq subject.occurrences.to_s
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
context 'using the :occurences token' do
|
186
|
+
it 'returns the formatted string' do
|
187
|
+
expect(subject.strfocc(':occurrences')).to eq subject.occurrences.to_s
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
context 'using the :duration token' do
|
192
|
+
subject { Duranged::Occurrence.new(5, 10.minutes, 30.seconds) }
|
193
|
+
|
194
|
+
it 'requires nested formatters' do
|
195
|
+
expect(subject.strfocc(':duration')).to eq ':duration'
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'returns the formatted string' do
|
199
|
+
expect(subject.strfocc(':duration(%d:%h:%m:%s)')).to eq subject.duration.strfdur('%d:%h:%m:%s')
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
context 'using the :interval token' do
|
204
|
+
it 'requires nested formatters' do
|
205
|
+
expect(subject.strfocc(':interval')).to eq ':interval'
|
206
|
+
end
|
207
|
+
|
208
|
+
it 'returns the formatted string' do
|
209
|
+
expect(subject.strfocc(':interval(%d:%h:%m:%s)')).to eq subject.interval.strfdur('%d:%h:%m:%s')
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
context 'using the :range token' do
|
214
|
+
subject { Duranged::Occurrence.new(5, 10.minutes, 30.seconds, Time.now, Time.now + 1.hour) }
|
215
|
+
|
216
|
+
context 'without nested formatters' do
|
217
|
+
it 'returns the default formatted range string' do
|
218
|
+
expect(subject.strfocc(':range')).to eq subject.range.to_s
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
context 'with nested formatters' do
|
223
|
+
it 'returns the formatted string' do
|
224
|
+
expect(subject.strfocc(':range(:start_at(%l:%M%P) :end_at(%l:%M%P) :duration(%D%H%M%S))')).to eq "#{subject.range.start_at('%l:%M%P')} #{subject.range.end_at('%l:%M%P')} #{subject.range.strfdur('%D%H%M%S')}"
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
context "using complex format string ':occurrences times for :duration(%-s) seconds every :interval(%-m) minutes between :range(:start_at(%l:%M%P) and :end_at(%l:%M%P) (:duration(%-m minutes)))'" do
|
230
|
+
subject { Duranged::Occurrence.new(3, 5.minutes, 30.seconds, DateTime.parse('2015-01-01T06:00:00-07:00'), DateTime.parse('2015-01-01T06:20:00-07:00')) }
|
231
|
+
|
232
|
+
it "returns '3 times for 30 seconds every 5 minutes between 6:00am and 6:20am'" do
|
233
|
+
expect(subject.strfocc(':occurrences times for :duration(%-s) seconds every :interval(%-m) minutes between :range(:start_at(%l:%M%P) and :end_at(%l:%M%P) (:duration(%-m minutes)))')).to eq '3 times for 30 seconds every 5 minutes between 6:00am and 6:20am (20 minutes)'
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
context "using complex format string 'between :range(:start_at(%l:%M%P) and :end_at(%l:%M%P) (:duration(%-m minutes))), do something :occurrences times for :duration(%-s) seconds every :interval(%-m) minutes'" do
|
238
|
+
subject { Duranged::Occurrence.new(3, 5.minutes, 30.seconds, DateTime.parse('2015-01-01T06:00:00-07:00'), DateTime.parse('2015-01-01T06:20:00-07:00')) }
|
239
|
+
|
240
|
+
it "returns 'between 6:00am and 6:20am (20 minutes), do something 3 times for 30 seconds every 5 minutes'" do
|
241
|
+
expect(subject.strfocc('between :range(:start_at(%l:%M%P) and :end_at(%l:%M%P) (:duration(%-m minutes))), do something :occurrences times for :duration(%-s) seconds every :interval(%-m) minutes')).to eq 'between 6:00am and 6:20am (20 minutes), do something 3 times for 30 seconds every 5 minutes'
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
@@ -0,0 +1,324 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.shared_examples "a format token" do |token, format, meth|
|
4
|
+
it 'requires nested formatters' do
|
5
|
+
expect(subject.strfrange("#{token}")).to eq "#{token}"
|
6
|
+
end
|
7
|
+
|
8
|
+
it "returns the formatted #{token}" do
|
9
|
+
expect(subject.strfrange("#{token}(#{format})")).to eq subject.send(meth, format)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
RSpec.describe Duranged::Range do
|
14
|
+
now = Time.now
|
15
|
+
subject { Duranged::Range.new(now, 60.minutes) }
|
16
|
+
|
17
|
+
describe 'dump' do
|
18
|
+
it 'dumps the time range as a JSON hash' do
|
19
|
+
expect(Duranged::Range.dump(subject)).to eq subject.to_json
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'load' do
|
24
|
+
it 'creates a new time range from a JSON hash' do
|
25
|
+
expect(Duranged::Range.load(subject.to_json)).to be_an_instance_of Duranged::Range
|
26
|
+
expect(Duranged::Range.load(subject.to_json).as_json).to eq subject.as_json
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#initialize' do
|
31
|
+
context 'with a start_at and end_at' do
|
32
|
+
subject { Duranged::Range.new(now, (now + 60.minutes)) }
|
33
|
+
|
34
|
+
it 'sets start_at' do
|
35
|
+
expect(subject.start_at).to eq now
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'sets end_at' do
|
39
|
+
expect(subject.end_at).to eq(now + 60.minutes)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'with a start_at and duration' do
|
44
|
+
subject { Duranged::Range.new(now, 60.minutes) }
|
45
|
+
|
46
|
+
it 'sets start_at' do
|
47
|
+
expect(subject.start_at).to eq now
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'when the duration is an ActiveSupport::Duration' do
|
51
|
+
subject { Duranged::Range.new(now, 60.minutes) }
|
52
|
+
|
53
|
+
it 'sets end_at to start_at + duration' do
|
54
|
+
expect(subject.end_at).to eq(now + 60.minutes)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'when the duration is an integer' do
|
59
|
+
subject { Duranged::Range.new(now, 3600) }
|
60
|
+
|
61
|
+
it 'sets end_at to start_at + duration' do
|
62
|
+
expect(subject.end_at).to eq(now + 60.minutes)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'when the duration is a hash' do
|
67
|
+
subject { Duranged::Range.new(now, {minutes: 60}) }
|
68
|
+
|
69
|
+
it 'sets end_at to start_at + duration' do
|
70
|
+
expect(subject.end_at).to eq(now + 60.minutes)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'when the duration is a string' do
|
75
|
+
subject { Duranged::Range.new(now, "1 day, 2 hours and 30 minutes") }
|
76
|
+
|
77
|
+
it 'sets end_at to start_at + duration' do
|
78
|
+
expect(subject.end_at).to eq(now + (26.hours + 30.minutes))
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'with just a duration' do
|
84
|
+
subject { Duranged::Range.new(60.minutes) }
|
85
|
+
|
86
|
+
it 'sets start_at to now' do
|
87
|
+
expect(subject.start_at).to be_between((Time.now - 1.seconds), Time.now)
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'when the duration is an ActiveSupport::Duration' do
|
91
|
+
subject { Duranged::Range.new(60.minutes) }
|
92
|
+
|
93
|
+
it 'sets end_at to start_at + duration' do
|
94
|
+
expect(subject.end_at).to eq(subject.start_at + 60.minutes)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context 'when the duration is an integer' do
|
99
|
+
subject { Duranged::Range.new(3600) }
|
100
|
+
|
101
|
+
it 'sets end_at to start_at + duration' do
|
102
|
+
expect(subject.end_at).to eq(subject.start_at + 60.minutes)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context 'when the duration is a hash' do
|
107
|
+
subject { Duranged::Range.new({minutes: 60}) }
|
108
|
+
|
109
|
+
it 'sets end_at to start_at + duration' do
|
110
|
+
expect(subject.end_at).to eq(subject.start_at + 60.minutes)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context 'with just an end_at' do
|
116
|
+
subject { Duranged::Range.new(now + 60.minutes) }
|
117
|
+
|
118
|
+
it 'sets start_at to now' do
|
119
|
+
expect(subject.start_at).to be_between((Time.now - 1.seconds), Time.now)
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'sets end_at' do
|
123
|
+
expect(subject.end_at).to eq(now + 60.minutes)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe '#start_at' do
|
129
|
+
subject { Duranged::Range.new(now, 60.minutes) }
|
130
|
+
|
131
|
+
context 'without a format argument' do
|
132
|
+
it 'returns the start_at DateTime object' do
|
133
|
+
expect(subject.start_at).to eq now
|
134
|
+
expect(subject.start_at).to be_an_instance_of DateTime
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context 'with a format argument' do
|
139
|
+
it 'returns a formatted string' do
|
140
|
+
expect(subject.start_at('%A, %b %e, %Y %l:%M%P')).to eq now.strftime('%A, %b %e, %Y %l:%M%P')
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe '#end_at' do
|
146
|
+
subject { Duranged::Range.new(now, 60.minutes) }
|
147
|
+
|
148
|
+
context 'without a format argument' do
|
149
|
+
it 'returns the end_at DateTime object' do
|
150
|
+
expect(subject.end_at).to eq(now + 60.minutes)
|
151
|
+
expect(subject.end_at).to be_an_instance_of DateTime
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
context 'with a format argument' do
|
156
|
+
it 'returns a formatted string' do
|
157
|
+
expect(subject.end_at('%A, %b %e, %Y %l:%M%P')).to eq((now + 60.minutes).strftime('%A, %b %e, %Y %l:%M%P'))
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe '#+' do
|
163
|
+
context 'when passed an integer' do
|
164
|
+
it 'returns an instance of the same class' do
|
165
|
+
expect(subject + 20).to be_an_instance_of subject.class
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'adds the integer to the value' do
|
169
|
+
expect((subject + 20).value).to eq (subject.value + 20)
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'recalculates the end_at' do
|
173
|
+
end_at = subject.end_at.to_i
|
174
|
+
expect((subject + 20).end_at.to_i).to eq (end_at + 20)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
context 'when passed a duration' do
|
179
|
+
it 'returns an instance of the same class' do
|
180
|
+
expect(subject + Duranged::Duration.new(20)).to be_an_instance_of subject.class
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'adds the duration to the value' do
|
184
|
+
expect((subject + Duranged::Duration.new(20)).value).to eq (subject.value + 20)
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'recalculates the end_at' do
|
188
|
+
end_at = subject.end_at.to_i
|
189
|
+
expect((subject + Duranged::Duration.new(20)).end_at.to_i).to eq (end_at + 20)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
context 'when passed an interval' do
|
194
|
+
it 'returns an instance of the same class' do
|
195
|
+
expect(subject + Duranged::Interval.new(20)).to be_an_instance_of subject.class
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'adds the interval to the value' do
|
199
|
+
expect((subject + Duranged::Interval.new(20)).value).to eq (subject.value + 20)
|
200
|
+
end
|
201
|
+
|
202
|
+
it 'recalculates the end_at' do
|
203
|
+
end_at = subject.end_at.to_i
|
204
|
+
expect((subject + Duranged::Interval.new(20)).end_at.to_i).to eq (end_at + 20)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
describe '#-' do
|
210
|
+
context 'when passed an integer' do
|
211
|
+
it 'returns an instance of the same class' do
|
212
|
+
expect(subject - 20).to be_an_instance_of subject.class
|
213
|
+
end
|
214
|
+
|
215
|
+
it 'adds the integer to the value' do
|
216
|
+
expect((subject - 20).value).to eq (subject.value - 20)
|
217
|
+
end
|
218
|
+
|
219
|
+
it 'recalculates the end_at' do
|
220
|
+
end_at = subject.end_at.to_i
|
221
|
+
expect((subject - 20).end_at.to_i).to eq (end_at - 20)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
context 'when passed a duration' do
|
226
|
+
it 'returns an instance of the same class' do
|
227
|
+
expect(subject - Duranged::Duration.new(20)).to be_an_instance_of subject.class
|
228
|
+
end
|
229
|
+
|
230
|
+
it 'adds the duration to the value' do
|
231
|
+
expect((subject - Duranged::Duration.new(20)).value).to eq (subject.value - 20)
|
232
|
+
end
|
233
|
+
|
234
|
+
it 'recalculates the end_at' do
|
235
|
+
end_at = subject.end_at.to_i
|
236
|
+
expect((subject - Duranged::Duration.new(20)).end_at.to_i).to eq (end_at - 20)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
context 'when passed an interval' do
|
241
|
+
it 'returns an instance of the same class' do
|
242
|
+
expect(subject - Duranged::Interval.new(20)).to be_an_instance_of subject.class
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'adds the interval to the value' do
|
246
|
+
expect((subject - Duranged::Interval.new(20)).value).to eq (subject.value - 20)
|
247
|
+
end
|
248
|
+
|
249
|
+
it 'recalculates the end_at' do
|
250
|
+
end_at = subject.end_at.to_i
|
251
|
+
expect((subject - Duranged::Interval.new(20)).end_at.to_i).to eq (end_at - 20)
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
describe '#to_h' do
|
257
|
+
it 'returns a hash with start_at and end_at' do
|
258
|
+
expect(subject.to_h).to eq({start_at: subject.start_at.as_json, end_at: subject.end_at.as_json})
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
describe '#as_json' do
|
263
|
+
it 'returns a hash with start_at and end_at' do
|
264
|
+
expect(subject.as_json).to eq({start_at: subject.start_at.as_json, end_at: subject.end_at.as_json})
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
describe '#to_duration' do
|
269
|
+
it 'returns a duration object' do
|
270
|
+
expect(subject.to_duration).to be_an_instance_of Duranged::Duration
|
271
|
+
end
|
272
|
+
|
273
|
+
it 'returns a duration object that represents the duration value' do
|
274
|
+
expect(subject.to_duration.duration).to eq subject.duration
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
describe '#to_s' do
|
279
|
+
subject { Duranged::Range.new((now.beginning_of_day), 60.minutes) }
|
280
|
+
let(:format) { '%-l:%M%P' }
|
281
|
+
|
282
|
+
it 'uses the default format' do
|
283
|
+
expect(subject.to_s).to eq "#{subject.start_at('%b. %-d %Y ' + format)} to #{subject.end_at(format)}"
|
284
|
+
end
|
285
|
+
|
286
|
+
context 'when start and end fall on the same day' do
|
287
|
+
subject { Duranged::Range.new((now.beginning_of_day + 30.minutes), (now.beginning_of_day + 5.hours)) }
|
288
|
+
|
289
|
+
it 'returns the start and end times' do
|
290
|
+
expect(subject.to_s).to eq "#{subject.start_at('%b. %-d %Y ' + format)} to #{subject.end_at(format)}"
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
context 'when start and end fall on different days' do
|
295
|
+
subject { Duranged::Range.new((now.utc.end_of_day - 20.minutes), 30.minutes) }
|
296
|
+
let(:format) { '%b. %-d %Y %-l:%M%P' }
|
297
|
+
|
298
|
+
it 'returns the start date/time and duration' do
|
299
|
+
expect(subject.to_s).to eq "#{subject.start_at(format)} (#{subject.to_duration.to_s})"
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
describe '#strfrange' do
|
305
|
+
context 'when using the :start_at token' do
|
306
|
+
it_behaves_like "a format token", ':start_at', '%b. %-d %Y %-l:%M%P', :start_at
|
307
|
+
end
|
308
|
+
|
309
|
+
context 'when using the :end_at token' do
|
310
|
+
it_behaves_like "a format token", ':end_at', '%b. %-d %Y %-l:%M%P', :end_at
|
311
|
+
end
|
312
|
+
|
313
|
+
context 'when using the :duration token' do
|
314
|
+
it_behaves_like "a format token", ':duration', '%D:%H:%M:%S', :strfdur
|
315
|
+
end
|
316
|
+
|
317
|
+
context "using complex format string ':start_at(%b. %-d %Y) :start_at(%l:%M%P) - :end_at(%l:%M%P) (:duration(%-h hours, %-m minutes))'" do
|
318
|
+
subject { Duranged::Range.new(DateTime.parse('2015-01-01T00:00:00-07:00'), DateTime.parse('2015-01-01T06:30:00-07:00')) }
|
319
|
+
it "returns 'Jan. 1 2015 12:00am - 6:30am (6 hours, 30 minutes)'" do
|
320
|
+
expect(subject.strfrange(':start_at(%b. %-d %Y) :start_at(%l:%M%P) - :end_at(%l:%M%P) (:duration(%-h hours, %-m minutes))')).to eq 'Jan. 1 2015 12:00am - 6:30am (6 hours, 30 minutes)'
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|