duranged 0.0.1
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 +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
|