time_frame 0.0.6 → 0.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.
@@ -26,11 +26,10 @@ Gem::Specification.new do |spec|
26
26
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
27
27
  spec.require_paths = ['lib']
28
28
 
29
- spec.add_development_dependency('rake')
30
- spec.add_development_dependency('rspec')
31
- spec.add_development_dependency('bundler')
32
- spec.add_development_dependency('simplecov')
33
- spec.add_development_dependency('rubocop')
34
- spec.add_dependency 'activesupport', '~> 4.0'
35
-
29
+ spec.add_development_dependency 'rake', '~> 10.3.2'
30
+ spec.add_development_dependency 'rspec', '~> 3.0.0'
31
+ spec.add_development_dependency 'bundler', '~> 1.6.1'
32
+ spec.add_development_dependency 'simplecov', '~> 0.8.2'
33
+ spec.add_development_dependency 'rubocop', '~> 0.23.0'
34
+ spec.add_dependency 'activesupport', '~> 4.1.1'
36
35
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: time_frame
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrick Derichs
@@ -10,92 +10,92 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2014-05-26 00:00:00.000000000 Z
13
+ date: 2014-07-16 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake
17
17
  requirement: !ruby/object:Gem::Requirement
18
18
  requirements:
19
- - - ! '>='
19
+ - - "~>"
20
20
  - !ruby/object:Gem::Version
21
- version: '0'
21
+ version: 10.3.2
22
22
  type: :development
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
- - - ! '>='
26
+ - - "~>"
27
27
  - !ruby/object:Gem::Version
28
- version: '0'
28
+ version: 10.3.2
29
29
  - !ruby/object:Gem::Dependency
30
30
  name: rspec
31
31
  requirement: !ruby/object:Gem::Requirement
32
32
  requirements:
33
- - - ! '>='
33
+ - - "~>"
34
34
  - !ruby/object:Gem::Version
35
- version: '0'
35
+ version: 3.0.0
36
36
  type: :development
37
37
  prerelease: false
38
38
  version_requirements: !ruby/object:Gem::Requirement
39
39
  requirements:
40
- - - ! '>='
40
+ - - "~>"
41
41
  - !ruby/object:Gem::Version
42
- version: '0'
42
+ version: 3.0.0
43
43
  - !ruby/object:Gem::Dependency
44
44
  name: bundler
45
45
  requirement: !ruby/object:Gem::Requirement
46
46
  requirements:
47
- - - ! '>='
47
+ - - "~>"
48
48
  - !ruby/object:Gem::Version
49
- version: '0'
49
+ version: 1.6.1
50
50
  type: :development
51
51
  prerelease: false
52
52
  version_requirements: !ruby/object:Gem::Requirement
53
53
  requirements:
54
- - - ! '>='
54
+ - - "~>"
55
55
  - !ruby/object:Gem::Version
56
- version: '0'
56
+ version: 1.6.1
57
57
  - !ruby/object:Gem::Dependency
58
58
  name: simplecov
59
59
  requirement: !ruby/object:Gem::Requirement
60
60
  requirements:
61
- - - ! '>='
61
+ - - "~>"
62
62
  - !ruby/object:Gem::Version
63
- version: '0'
63
+ version: 0.8.2
64
64
  type: :development
65
65
  prerelease: false
66
66
  version_requirements: !ruby/object:Gem::Requirement
67
67
  requirements:
68
- - - ! '>='
68
+ - - "~>"
69
69
  - !ruby/object:Gem::Version
70
- version: '0'
70
+ version: 0.8.2
71
71
  - !ruby/object:Gem::Dependency
72
72
  name: rubocop
73
73
  requirement: !ruby/object:Gem::Requirement
74
74
  requirements:
75
- - - ! '>='
75
+ - - "~>"
76
76
  - !ruby/object:Gem::Version
77
- version: '0'
77
+ version: 0.23.0
78
78
  type: :development
79
79
  prerelease: false
80
80
  version_requirements: !ruby/object:Gem::Requirement
81
81
  requirements:
82
- - - ! '>='
82
+ - - "~>"
83
83
  - !ruby/object:Gem::Version
84
- version: '0'
84
+ version: 0.23.0
85
85
  - !ruby/object:Gem::Dependency
86
86
  name: activesupport
87
87
  requirement: !ruby/object:Gem::Requirement
88
88
  requirements:
89
- - - ~>
89
+ - - "~>"
90
90
  - !ruby/object:Gem::Version
91
- version: '4.0'
91
+ version: 4.1.1
92
92
  type: :runtime
93
93
  prerelease: false
94
94
  version_requirements: !ruby/object:Gem::Requirement
95
95
  requirements:
96
- - - ~>
96
+ - - "~>"
97
97
  - !ruby/object:Gem::Version
98
- version: '4.0'
98
+ version: 4.1.1
99
99
  description: TimeFrame
100
100
  email:
101
101
  - patrick.derichs@invision.de
@@ -105,13 +105,14 @@ executables: []
105
105
  extensions: []
106
106
  extra_rdoc_files: []
107
107
  files:
108
- - .gitignore
109
- - .rubocop.yml
110
- - .travis.yml
108
+ - ".gitignore"
109
+ - ".rubocop.yml"
110
+ - ".travis.yml"
111
111
  - Gemfile
112
112
  - README.md
113
113
  - Rakefile
114
114
  - lib/time_frame.rb
115
+ - lib/time_frame/empty.rb
115
116
  - lib/time_frame/time_frame.rb
116
117
  - lib/time_frame/time_frame_covered.rb
117
118
  - lib/time_frame/time_frame_overlaps.rb
@@ -119,7 +120,7 @@ files:
119
120
  - lib/time_frame/time_frame_uniter.rb
120
121
  - lib/time_frame/version.rb
121
122
  - spec/spec_helper.rb
122
- - spec/time_range_spec.rb
123
+ - spec/time_frame_spec.rb
123
124
  - time_frame.gemspec
124
125
  homepage: https://github.com/injixo/time_frame
125
126
  licenses:
@@ -131,12 +132,12 @@ require_paths:
131
132
  - lib
132
133
  required_ruby_version: !ruby/object:Gem::Requirement
133
134
  requirements:
134
- - - ! '>='
135
+ - - ">="
135
136
  - !ruby/object:Gem::Version
136
137
  version: 2.0.0
137
138
  required_rubygems_version: !ruby/object:Gem::Requirement
138
139
  requirements:
139
- - - ! '>='
140
+ - - ">="
140
141
  - !ruby/object:Gem::Version
141
142
  version: '0'
142
143
  requirements: []
@@ -147,4 +148,4 @@ specification_version: 4
147
148
  summary: Ruby gem that offers support for time frames
148
149
  test_files:
149
150
  - spec/spec_helper.rb
150
- - spec/time_range_spec.rb
151
+ - spec/time_frame_spec.rb
@@ -1,1081 +0,0 @@
1
- # Encoding: utf-8
2
- require 'spec_helper'
3
-
4
- describe TimeFrame do
5
- let(:time) { Time.zone.local(2012) }
6
- let(:duration) { 2.hours }
7
-
8
- before do
9
- # Avoid i18n deprecation warning
10
- I18n.enforce_available_locales = true
11
- end
12
-
13
- describe '#initialize' do
14
- context 'when given two times' do
15
- context 'and min is smaller than max' do
16
- subject { TimeFrame.new(min: time, max: time + duration) }
17
-
18
- describe '#min' do
19
- subject { super().min }
20
- it { should eq time }
21
- end
22
-
23
- describe '#max' do
24
- subject { super().max }
25
- it { should eq time + duration }
26
- end
27
- end
28
- context 'and max is smaller than min' do
29
- specify do
30
- expect do
31
- TimeFrame.new(min: time, max: time - 1.day)
32
- end.to raise_error(ArgumentError)
33
- end
34
- end
35
- context 'which are equal' do
36
- subject { TimeFrame.new(min: time, max: time) }
37
-
38
- describe '#min' do
39
- subject { super().min }
40
- it { should eq time }
41
- end
42
-
43
- describe '#max' do
44
- subject { super().max }
45
- it { should eq time }
46
- end
47
- end
48
- end
49
-
50
- context 'when time and duration is given' do
51
- context ' and duration is positive' do
52
- subject { TimeFrame.new(min: time, duration: 1.hour) }
53
-
54
- describe '#min' do
55
- subject { super().min }
56
- it { should eq time }
57
- end
58
-
59
- describe '#max' do
60
- subject { super().max }
61
- it { should eq time + 1.hour }
62
- end
63
- end
64
- context 'and duration is negative' do
65
- let(:invalid_t_r) { TimeFrame.new(min: time, duration: - 1.hour) }
66
- specify { expect { invalid_t_r }.to raise_error }
67
- end
68
- context 'and duration is 0' do
69
- subject { TimeFrame.new(min: time, duration: 0.hour) }
70
-
71
- describe '#min' do
72
- subject { super().min }
73
- it { should eq time }
74
- end
75
-
76
- describe '#max' do
77
- subject { super().max }
78
- it { should eq time }
79
- end
80
- end
81
- context 'and time frame covers a DST shift' do
82
- let(:time) do
83
- Time.use_zone('Europe/Berlin') { Time.zone.local(2013, 10, 27) }
84
- end
85
- subject { TimeFrame.new(min: time, duration: 1.day) }
86
-
87
- describe '#min' do
88
- subject { super().min }
89
- it { should eq time }
90
- end
91
-
92
- describe '#max' do
93
- subject { super().max }
94
- it { should eq time + 25.hours }
95
- end
96
- end
97
- end
98
- end
99
-
100
- describe '#duration' do
101
- context 'when borders are different' do
102
- subject { TimeFrame.new(min: time, duration: 2.hours).duration }
103
- it { should eq 2.hours }
104
- end
105
- context 'when borders are equal' do
106
- subject { TimeFrame.new(min: time, max: time).duration }
107
- it { should eq 0 }
108
- end
109
- context 'when time frame containts a DST shift' do
110
- it 'should gain 1 hour on summer -> winter shifts' do
111
- Time.use_zone('Europe/Berlin') do
112
- time_frame = TimeFrame.new(min: Time.zone.local(2013, 10, 27),
113
- max: Time.zone.local(2013, 10, 28))
114
- expect(time_frame.duration).to eq 25.hours
115
- end
116
- end
117
- it 'should lose 1 hour on winter -> summer shifts' do
118
- Time.use_zone('Europe/Berlin') do
119
- time_frame = TimeFrame.new(min: Time.zone.local(2013, 3, 31),
120
- max: Time.zone.local(2013, 4, 1))
121
- expect(time_frame.duration).to eq 23.hours
122
- end
123
- end
124
- end
125
- end
126
-
127
- describe '#==' do
128
- let(:frame) { TimeFrame.new(min: time, duration: 2.hours) }
129
- context 'when borders are equal' do
130
- let(:other) { TimeFrame.new(min: time, duration: 2.hours) }
131
- subject { frame == other }
132
- it { should be_true }
133
- end
134
- context 'when min value is different' do
135
- let(:other) do
136
- TimeFrame.new(min: time - 1.hour, max: time + 2.hours)
137
- end
138
- subject { frame == other }
139
- it { should be_false }
140
- end
141
- context 'when max value is different' do
142
- let(:other) { TimeFrame.new(min: time, duration: 3.hours) }
143
- subject { frame == other }
144
- it { should be_false }
145
- end
146
- end
147
-
148
- describe '#cover?' do
149
- let(:frame) { TimeFrame.new(min: time, duration: 4.hours) }
150
- context 'when argument is a Time instance' do
151
- context 'and its covered' do
152
- context 'and equal to min' do
153
- subject { frame.cover?(frame.min) }
154
- it { should be_true }
155
- end
156
- context 'and equal to max' do
157
- subject { frame.cover?(frame.max) }
158
- it { should be_true }
159
- end
160
- context 'and is an inner value' do
161
- subject { frame.cover?(frame.min + 1.hour) }
162
- it { should be_true }
163
- end
164
- end
165
- context 'and its not covered' do
166
- context 'and smaller than min' do
167
- subject { frame.cover?(frame.min - 1.hour) }
168
- it { should be_false }
169
- end
170
- context 'and greater than max' do
171
- subject { frame.cover?(frame.max + 5.hours) }
172
- it { should be_false }
173
- end
174
- end
175
- end
176
- context 'when argument is a TimeFrame' do
177
- context 'and its covered' do
178
- context 'and they have the same min value' do
179
- let(:other) { TimeFrame.new(min: frame.min, duration: 2.hours) }
180
- subject { frame.cover?(other) }
181
- it { should be_true }
182
- end
183
- context 'and they have the same max value' do
184
- let(:other) do
185
- TimeFrame.new(min: frame.min + 1.hour, max: frame.max)
186
- end
187
- subject { frame.cover?(other) }
188
- it { should be_true }
189
- end
190
- context 'and it is within the interior of self' do
191
- let(:other) do
192
- TimeFrame.new(min: frame.min + 1.hour, max: frame.max - 1.hour)
193
- end
194
- subject { frame.cover?(other) }
195
- it { should be_true }
196
- end
197
- context 'and are equal' do
198
- let(:other) { frame.clone }
199
- subject { frame.cover?(other) }
200
- it { should be_true }
201
- end
202
- end
203
- context 'and it is not covered' do
204
- context 'and other is left of self' do
205
- let(:other) { frame.shift_by(-5.hours) }
206
- subject { frame.cover?(other) }
207
- it { should be_false }
208
- end
209
- context 'and other overlaps left hand side' do
210
- let(:other) { frame.shift_by(-1.hour) }
211
- subject { frame.cover?(other) }
212
- it { should be_false }
213
- end
214
- context 'and other overlaps left hand side at the border only' do
215
- let(:other) { frame.shift_by(-frame.duration) }
216
- subject { frame.cover?(other) }
217
- it { should be_false }
218
- end
219
- context 'and other is right of self' do
220
- let(:other) { frame.shift_by(5.hours) }
221
- subject { frame.cover?(other) }
222
- it { should be_false }
223
- end
224
- context 'and other overlaps right hand side' do
225
- let(:other) { frame.shift_by(1.hours) }
226
- subject { frame.cover?(other) }
227
- it { should be_false }
228
- end
229
- context 'and other overlaps right hand side at the border only' do
230
- let(:other) { frame.shift_by(frame.duration) }
231
- subject { frame.cover?(other) }
232
- it { should be_false }
233
- end
234
- end
235
- end
236
- end
237
-
238
- describe '#deviation_of' do
239
- let(:time_frame) do
240
- TimeFrame.new(min: Time.zone.local(2012), duration: 2.days)
241
- end
242
- context 'when providing a time object' do
243
- describe 'when self covers time' do
244
- context 'and time equals min' do
245
- let(:time) { time_frame.min }
246
- subject { time_frame.deviation_of(time) }
247
- it { should eq 0.minutes }
248
- end
249
- context 'and time equals max' do
250
- let(:time) { time_frame.max }
251
- subject { time_frame.deviation_of(time) }
252
- it { should eq 0.minutes }
253
- end
254
- context 'and time is an interior point of self' do
255
- let(:time) { time_frame.min + (time_frame.duration / 2.0) }
256
- subject { time_frame.deviation_of(time) }
257
- it { should eq 0.minutes }
258
- end
259
- end
260
- context 'when self do not cover time' do
261
- context 'and time is smaller than the left bound' do
262
- let(:time) { time_frame.min - 42.hours - 42.minutes }
263
- subject { time_frame.deviation_of(time) }
264
- it { should eq(-42.hours - 42.minutes) }
265
- end
266
- context 'and time is greater than the right bound' do
267
- let(:time) { time_frame.max + 42.hours + 42.minutes }
268
- subject { time_frame.deviation_of(time) }
269
- it { should eq 42.hours + 42.minutes }
270
- end
271
- end
272
- end
273
- context 'when providing a time_frame' do
274
- describe 'when self overlaps other' do
275
- context 'and its partly' do
276
- let(:other) { time_frame.shift_by(time_frame.duration / 2) }
277
- subject { time_frame.deviation_of(other) }
278
- it { should eq 0.minutes }
279
- end
280
- context 'and time equals max' do
281
- let(:other) { time_frame }
282
- subject { time_frame.deviation_of(other) }
283
- it { should eq 0.minutes }
284
- end
285
- context 'and other lies in the interior of self' do
286
- let(:other) do
287
- TimeFrame.new(min: time_frame.min + 1.hour, duration: 1.hour)
288
- end
289
- subject { time_frame.deviation_of(other) }
290
- it { should eq 0.minutes }
291
- end
292
- end
293
- context 'when self do not cover time' do
294
- context 'and time is smaller than the left bound' do
295
- let(:other) { time_frame.shift_by(-2.days - 42.seconds) }
296
- subject { time_frame.deviation_of(other) }
297
- it { should eq(-42.seconds) }
298
- end
299
- context 'and time is greater than the right bound' do
300
- let(:other) { time_frame.shift_by(2.days + 42.seconds) }
301
- subject { time_frame.deviation_of(other) }
302
- it { should eq 42.seconds }
303
- end
304
- end
305
- end
306
- end
307
-
308
- describe '#split_to_interval' do
309
- let(:time_frame) do
310
- TimeFrame.new(min: Time.zone.local(2012), duration: 1.day)
311
- end
312
- context 'when time frame duration is divisible by interval' do
313
- context 'and interval length equals duration' do
314
- subject { time_frame.split_by_interval(1.day) }
315
- it { should eq [time_frame] }
316
- end
317
- context 'and interval is smaller than duration' do
318
- let(:first_time_frame) do
319
- TimeFrame.new(min: time_frame.min, duration: 12.hours)
320
- end
321
- subject { time_frame.split_by_interval(12.hours) }
322
- it do
323
- should eq [first_time_frame, first_time_frame.shift_by(12.hours)]
324
- end
325
- end
326
- context 'and frame starts at a time, not divisible by interval' do
327
- let(:other_time_frame) do
328
- TimeFrame.new(
329
- min: Time.zone.local(2012) + 1.minute,
330
- duration: 1.day
331
- )
332
- end
333
- let(:first_time_frame) do
334
- TimeFrame.new(min: other_time_frame.min, duration: 12.hours)
335
- end
336
- subject { other_time_frame.split_by_interval(12.hours) }
337
- it do
338
- should eq [first_time_frame, first_time_frame.shift_by(12.hours)]
339
- end
340
- end
341
- end
342
- context 'when time frame duration is not divisible by interval' do
343
- let(:expected) do
344
- [
345
- TimeFrame.new(min: time_frame.min, duration: 18.hours),
346
- TimeFrame.new(min: time_frame.min + 18.hours, duration: 6.hours)
347
- ]
348
- end
349
- subject { time_frame.split_by_interval(18.hours) }
350
- it { should eq expected }
351
- end
352
- end
353
-
354
- describe '#empty?' do
355
- context 'when min equals max' do
356
- subject { TimeFrame.new(min: time, max: time) }
357
- it { should be_empty }
358
- end
359
-
360
- context 'when max is greater than min' do
361
- subject { TimeFrame.new(min: time, duration: 1.day) }
362
- it { should_not be_empty }
363
- end
364
- end
365
-
366
- describe '.union' do
367
-
368
- context 'when given an empty array' do
369
- subject { TimeFrame.union([]) }
370
- it { should eq [] }
371
- end
372
-
373
- context 'when given a single time frame' do
374
- let(:frame) { TimeFrame.new(min: time, duration: 1.hour) }
375
- subject { TimeFrame.union([frame]) }
376
- it { should eq [frame] }
377
- end
378
-
379
- context 'when getting single element it returns a dup' do
380
- let(:frames) { [TimeFrame.new(min: time, duration: 1.hour)] }
381
- subject { TimeFrame.union(frames) }
382
- it { should_not equal frames }
383
- end
384
-
385
- context 'when given time frames' do
386
- context 'in order' do
387
- context 'and no sorted flag is provided' do
388
- context 'that are overlapping' do
389
- let(:frame1) { TimeFrame.new(min: time, duration: 2.hours) }
390
- let(:frame2) { frame1.shift_by(1.hour) }
391
- let(:expected) do
392
- [TimeFrame.new(min: frame1.min, max: frame2.max)]
393
- end
394
- subject { TimeFrame.union([frame1, frame2]) }
395
- it { should eq expected }
396
- end
397
- context 'that are disjoint' do
398
- let(:frame1) { TimeFrame.new(min: time, duration: 2.hours) }
399
- let(:frame2) { frame1.shift_by(3.hours) }
400
- subject { TimeFrame.union([frame1, frame2]) }
401
- it { should eq [frame1, frame2] }
402
- end
403
- context 'that intersect at their boundaries' do
404
- let(:frame1) { TimeFrame.new(min: time, duration: + 2.hour) }
405
- let(:frame2) { frame1.shift_by(frame1.duration) }
406
- let(:expected) do
407
- [TimeFrame.new(min: frame1.min, max: frame2.max)]
408
- end
409
- subject { TimeFrame.union([frame1, frame2]) }
410
- it { should eq expected }
411
- end
412
- end
413
- context 'and the sorted flag is provided' do
414
- context 'that are overlapping' do
415
- let(:frame1) { TimeFrame.new(min: time, duration: 2.hours) }
416
- let(:frame2) { frame1.shift_by(1.hour) }
417
- let(:expected) do
418
- [TimeFrame.new(min: frame1.min, max: frame2.max)]
419
- end
420
- subject { TimeFrame.union([frame1, frame2], sorted: true) }
421
- it { should eq expected }
422
- end
423
- context 'that are disjoint' do
424
- let(:frame1) { TimeFrame.new(min: time, duration: 2.hours) }
425
- let(:frame2) { frame1.shift_by(3.hours) }
426
- subject { TimeFrame.union([frame1, frame2], sorted: true) }
427
- it { should eq [frame1, frame2] }
428
- end
429
- context 'that intersect at their boundaries' do
430
- let(:frame1) { TimeFrame.new(min: time, duration: + 2.hour) }
431
- let(:frame2) { frame1.shift_by(frame1.duration) }
432
- let(:expected) do
433
- [TimeFrame.new(min: frame1.min, max: frame2.max)]
434
- end
435
- subject { TimeFrame.union([frame1, frame2], sorted: true) }
436
- it { should eq expected }
437
- end
438
- end
439
- end
440
- context 'not in order' do
441
- context 'that are overlapping' do
442
- let(:frame1) { TimeFrame.new(min: time, duration: 2.hours) }
443
- let(:frame2) { frame1.shift_by(1.hour) }
444
- subject { TimeFrame.union([frame2, frame1]) }
445
- it { should eq [TimeFrame.new(min: frame1.min, max: frame2.max)] }
446
- end
447
- context 'that are disjoint' do
448
- let(:frame1) { TimeFrame.new(min: time, duration: 2.hours) }
449
- let(:frame2) { frame1.shift_by(3.hours) }
450
- subject { TimeFrame.union([frame2, frame1]) }
451
- it { should eq [frame1, frame2] }
452
- end
453
- context 'that intersect at their boundaries' do
454
- let(:frame1) { TimeFrame.new(min: time, duration: + 2.hour) }
455
- let(:frame2) { frame1.shift_by(frame1.duration) }
456
- subject { TimeFrame.union([frame2, frame1]) }
457
- it { should eq [TimeFrame.new(min: frame1.min, max: frame2.max)] }
458
- end
459
- end
460
- end
461
- end
462
-
463
- describe '.intersection' do
464
- it 'returns the intersection of all time frames' do
465
- frame1 = TimeFrame.new(min: Time.zone.local(2012), duration: 3.days)
466
- frame2 = frame1.shift_by(-1.day)
467
- frame3 = frame1.shift_by(-2.days)
468
- expect(TimeFrame.intersection([frame1, frame2, frame3]))
469
- .to eq TimeFrame.new(min: Time.zone.local(2012), duration: 1.day)
470
- end
471
- it 'returns nil if the intersection is empty' do
472
- frame1 = TimeFrame.new(min: Time.zone.local(2012), duration: 1.days)
473
- frame2 = frame1.shift_by(-2.day)
474
- frame3 = frame1.shift_by(-4.days)
475
- expect(TimeFrame.intersection([frame1, frame2, frame3])).to be_nil
476
- end
477
- end
478
-
479
- describe '#overlaps?' do
480
- let(:frame) { TimeFrame.new(min: time, duration: 3.hours) }
481
- context 'when self is equal to other' do
482
- let(:other) { frame.clone }
483
- subject { frame.overlaps?(other) }
484
- it { should be_true }
485
- end
486
- context 'when self covers other' do
487
- let(:other) do
488
- TimeFrame.new(min: frame.min + 1.hour, max: frame.max - 1.hour)
489
- end
490
- subject { frame.overlaps?(other) }
491
- it { should be_true }
492
- end
493
- context 'when other covers self' do
494
- let(:other) do
495
- TimeFrame.new(min: frame.min - 1.hour, max: frame.max + 1.hour)
496
- end
497
- subject { frame.overlaps?(other) }
498
- it { should be_true }
499
- end
500
- context 'when self begins earlier than other' do
501
- context 'and they are disjoint' do
502
- let(:other) { frame.shift_by(-frame.duration - 1.hour) }
503
- subject { frame.overlaps?(other) }
504
- it { should be_false }
505
- end
506
- context 'and they are overlapping' do
507
- let(:other) { frame.shift_by(-1.hours) }
508
- subject { frame.overlaps?(other) }
509
- it { should be_true }
510
- end
511
- context 'and they intersect at their boundaries' do
512
- let(:other) { frame.shift_by(-frame.duration) }
513
- subject { frame.overlaps?(other) }
514
- it { should be_false }
515
- end
516
- end
517
- context 'when other begins earlier than self' do
518
- context 'and they are disjoint' do
519
- let(:other) { frame.shift_by(frame.duration + 1.hour) }
520
- subject { frame.overlaps?(other) }
521
- it { should be_false }
522
- end
523
- context 'and they are overlapping' do
524
- let(:other) { frame.shift_by(1.hours) }
525
- subject { frame.overlaps?(other) }
526
- it { should be_true }
527
- end
528
- context 'and they intersect at their boundaries' do
529
- let(:other) { frame.shift_by(frame.duration) }
530
- subject { frame.overlaps?(other) }
531
- it { should be_false }
532
- end
533
- end
534
- end
535
-
536
- describe '#&' do
537
- let(:frame) { TimeFrame.new(min: time, duration: 3.hours) }
538
- context 'when self is equal to other' do
539
- let(:other) { frame.clone }
540
- subject { frame & other }
541
- it { should eq frame }
542
- end
543
- context 'when self covers other' do
544
- let(:other) do
545
- TimeFrame.new(min: frame.min + 1.hour, max: frame.max - 1.hour)
546
- end
547
- subject { frame & other }
548
- it { should eq other }
549
- end
550
- context 'when other covers self' do
551
- let(:other) do
552
- TimeFrame.new(min: frame.min - 1.hour, max: frame.max + 1.hour)
553
- end
554
- subject { frame & other }
555
- it { should eq frame }
556
- end
557
- context 'when self begins earlier than other' do
558
- context 'and they are disjoint' do
559
- let(:other) { frame.shift_by(frame.duration + 1.hour) }
560
- subject { frame & other }
561
- it { should be_nil }
562
- end
563
- context 'and they are overlapping' do
564
- let(:other) { frame.shift_by(1.hour) }
565
- subject { frame & other }
566
- it { should eq TimeFrame.new(min: other.min, max: frame.max) }
567
- end
568
- context 'and they intersect at their boundaries' do
569
- let(:other) { frame.shift_by(frame.duration) }
570
- subject { frame & other }
571
- it { should eq TimeFrame.new(min: frame.max, max: frame.max) }
572
- end
573
- end
574
- context 'when other begins earlier than self' do
575
- context 'and they are disjoint' do
576
- let(:other) { frame.shift_by(-frame.duration - 1.hour) }
577
- subject { frame & other }
578
- it { should be_nil }
579
- end
580
- context 'and they are overlapping' do
581
- let(:other) { frame.shift_by(-1.hour) }
582
- subject { frame & other }
583
- it { should eq TimeFrame.new(min: frame.min, max: other.max) }
584
- end
585
- context 'and they intersect at their boundaries' do
586
- let(:other) { frame.shift_by(-frame.duration) }
587
- subject { frame & other }
588
- it { should eq TimeFrame.new(min: frame.min, max: frame.min) }
589
- end
590
- end
591
- end
592
-
593
- describe '#split_by_interval' do
594
- context 'when time frame duration is divisible by interval' do
595
- let(:time) { Time.new(2012, 1, 1) }
596
- let(:interval) { 1.day }
597
- let(:time_frame) do
598
- TimeFrame.new(min: time, duration: 7.days)
599
- end
600
- subject do
601
- time_frame.split_by_interval(interval)
602
- end
603
-
604
- describe '#size' do
605
- subject { super().size }
606
- it { should eq 7 }
607
- end
608
- (0..6).each do |day|
609
- it "should have the right borders on day #{day}" do
610
- expected = TimeFrame.new(min: time, duration: interval)
611
- expect(subject[day]).to eq expected.shift_by(day.days)
612
- end
613
- end
614
- end
615
-
616
- context 'when time frame duration is not divisible by interval' do
617
- let(:time) { Time.new(2012, 1, 1) }
618
- let(:interval) { 1.day }
619
- let(:time_frame) do
620
- TimeFrame.new(min: time, duration: 7.days + 12.hours)
621
- end
622
- subject do
623
- time_frame.split_by_interval(interval)
624
- end
625
-
626
- describe '#size' do
627
- subject { super().size }
628
- it { should eq 8 }
629
- end
630
- (0..6).each do |day|
631
- it "should have the right borders on day #{day}" do
632
- expected = TimeFrame.new(min: time, duration: interval)
633
- expect(subject[day]).to eq expected.shift_by(day.days)
634
- end
635
- end
636
- it 'should have a smaller frame at the end' do
637
- expected = TimeFrame.new(min: time + 7.days, duration: 12.hours)
638
- expect(subject[7]).to eq expected
639
- end
640
- end
641
- end
642
-
643
- describe '#shift_by' do
644
- let(:min) { time }
645
- let(:max) { time + 2.days }
646
- let(:frame) { TimeFrame.new(min: min, max: max) }
647
- context 'when shifting into the future' do
648
- subject { frame.shift_by(1.day) }
649
-
650
- describe '#min' do
651
- subject { super().min }
652
- it { should eq min + 1.day }
653
- end
654
-
655
- describe '#max' do
656
- subject { super().max }
657
- it { should eq max + 1.day }
658
- end
659
- it { should_not equal frame }
660
- end
661
- context 'when shifting into the past' do
662
- subject { frame.shift_by(-1.day) }
663
-
664
- describe '#min' do
665
- subject { super().min }
666
- it { should eq min - 1.day }
667
- end
668
-
669
- describe '#max' do
670
- subject { super().max }
671
- it { should eq max - 1.day }
672
- end
673
- it { should_not equal frame }
674
- end
675
- context 'when shifting by 0' do
676
- subject { frame.shift_by(0) }
677
-
678
- describe '#min' do
679
- subject { super().min }
680
- it { should eq min }
681
- end
682
-
683
- describe '#max' do
684
- subject { super().max }
685
- it { should eq max }
686
- end
687
- it { should_not equal frame }
688
- end
689
- context 'when shifting back and forth' do
690
- subject { frame.shift_by(-1.day).shift_by(1.day) }
691
-
692
- describe '#min' do
693
- subject { super().min }
694
- it { should eq min }
695
- end
696
-
697
- describe '#max' do
698
- subject { super().max }
699
- it { should eq max }
700
- end
701
- it { should_not equal frame }
702
- end
703
- end
704
-
705
- describe '#shift_to' do
706
-
707
- let(:duration) { 1.day }
708
- let(:min) { Time.zone.local(2012, 1, 2) }
709
- let(:max) { min + duration }
710
- let(:frame) { TimeFrame.new(min: min, max: max) }
711
-
712
- context 'when shifting to a future time' do
713
- let(:destination) { min + duration }
714
- subject { frame.shift_to(destination) }
715
- it { should_not equal frame }
716
-
717
- describe '#min' do
718
- subject { super().min }
719
- it { should eq destination }
720
- end
721
-
722
- describe '#max' do
723
- subject { super().max }
724
- it { should eq destination + duration }
725
- end
726
- end
727
-
728
- context 'when shifting to a past time' do
729
- let(:destination) { min - duration }
730
- subject { frame.shift_to(destination) }
731
- it { should_not equal frame }
732
-
733
- describe '#min' do
734
- subject { super().min }
735
- it { should eq destination }
736
- end
737
-
738
- describe '#max' do
739
- subject { super().max }
740
- it { should eq destination + duration }
741
- end
742
- end
743
-
744
- context 'when shifting to same time' do
745
- let(:destination) { min }
746
- subject { frame.shift_to(destination) }
747
- it { should_not equal frame }
748
-
749
- describe '#min' do
750
- subject { super().min }
751
- it { should eq destination }
752
- end
753
-
754
- describe '#max' do
755
- subject { super().max }
756
- it { should eq destination + duration }
757
- end
758
- end
759
- end
760
-
761
- describe '#without' do
762
- context 'when providing a single frame' do
763
- let(:frame) { TimeFrame.new(min: time, duration: 1.hour) }
764
-
765
- context 'and other is left of self' do
766
- context 'and they have a common border' do
767
- let(:other) { frame.shift_by(-frame.duration) }
768
- subject { frame.without(other) }
769
- it { should eq [frame] }
770
- end
771
- context 'and they do not have a common border' do
772
- let(:other) { frame.shift_by(-2 * frame.duration) }
773
- subject { frame.without(other) }
774
- it { should eq [frame] }
775
- end
776
- context 'and they overlap' do
777
- let(:other) { frame.shift_by(-0.5 * frame.duration) }
778
- subject { frame.without(other) }
779
- it { should eq [TimeFrame.new(min: other.max, max: frame.max)] }
780
- end
781
- end
782
-
783
- context 'and other is right of self' do
784
- context 'and they have a common border' do
785
- let(:other) { frame.shift_by(frame.duration) }
786
- subject { frame.without(other) }
787
- it { should eq [frame] }
788
- end
789
- context 'and they do not have a common border' do
790
- let(:other) { frame.shift_by(2 * frame.duration) }
791
- subject { frame.without(other) }
792
- it { should eq [frame] }
793
- end
794
- context 'and they overlap' do
795
- let(:other) { frame.shift_by(0.5 * frame.duration) }
796
- subject { frame.without(other) }
797
- it { should eq [TimeFrame.new(min: frame.min, max: other.min)] }
798
- end
799
- end
800
-
801
- context 'and other is contained within self' do
802
- context 'and other is equal to self' do
803
- subject { frame.without(frame) }
804
- it { should eq [] }
805
- end
806
- context 'and only left boundaries are equal' do
807
- let(:other) do
808
- TimeFrame.new(min: time, duration: frame.duration / 2)
809
- end
810
- subject { frame.without(other) }
811
- it { should eq [TimeFrame.new(min: other.max, max: frame.max)] }
812
- end
813
- context 'and only right boundaries are equal' do
814
- let(:other) do
815
- TimeFrame.new(min: time + frame.duration / 2, max: frame.max)
816
- end
817
- subject { frame.without(other) }
818
- it { should eq [TimeFrame.new(min: frame.min, max: other.min)] }
819
- end
820
- context 'and they have no boundary in common' do
821
- let(:other) do
822
- TimeFrame.new(min: time + frame.duration / 3,
823
- duration: frame.duration / 3)
824
- end
825
- subject { frame.without(other) }
826
- it do
827
- should eq [
828
- TimeFrame.new(min: frame.min, max: other.min),
829
- TimeFrame.new(min: other.max, max: frame.max)
830
- ]
831
- end
832
- end
833
- end
834
- end
835
-
836
- context 'when providing an array' do
837
- let(:frame) { TimeFrame.new(min: time, duration: 10.hours) }
838
- context 'and providing one frame' do
839
- context 'and its equal to self' do
840
- let(:arg) { [frame] }
841
- subject { frame.without(*arg) }
842
- it { should eq [] }
843
- end
844
- end
845
- context 'and providing several frames' do
846
- context 'and they do not intersect' do
847
- context 'and do not touch the boundaries' do
848
- let(:arg) do
849
- shift = frame.duration + 1.hour
850
- [
851
- TimeFrame.new(min: time - 2.hours, duration: 1.hour),
852
- TimeFrame.new(min: time + shift, duration: 1.hour)
853
- ]
854
- end
855
- subject { frame.without(*arg) }
856
- it { should eq [frame] }
857
- end
858
- context 'and they touch boundaries' do
859
- let(:arg) do
860
- [
861
- TimeFrame.new(min: time - 1.hour, duration: 1.hour),
862
- TimeFrame.new(min: time + frame.duration, duration: 1.hour)
863
- ]
864
- end
865
- subject { frame.without(*arg) }
866
- it { should eq [frame] }
867
- end
868
- end
869
- context 'and they intersect' do
870
- context 'and the argument frames overlaps themself' do
871
- let(:arg) do
872
- [
873
- TimeFrame.new(min: time + 1.hour, duration: 2.hours),
874
- TimeFrame.new(min: time + 2.hours, duration: 2.hours)
875
- ]
876
- end
877
- let(:expected) do
878
- [
879
- TimeFrame.new(min: frame.min, duration: 1.hour),
880
- TimeFrame.new(min: time + 4.hours, max: frame.max)
881
- ]
882
- end
883
- subject { frame.without(*arg) }
884
- it { should eq expected }
885
- end
886
- context 'and they cover self' do
887
- let(:arg) do
888
- duration = 0.5 * frame.duration
889
- [
890
- TimeFrame.new(min: time, duration: duration),
891
- TimeFrame.new(min: time + duration, duration: duration)
892
- ]
893
- end
894
- subject { frame.without(*arg) }
895
- it { should eq [] }
896
- end
897
- context 'and they overlap at the boundaries' do
898
- let(:arg) do
899
- shift = frame.duration - 1.hour
900
- [
901
- TimeFrame.new(min: time - 1.hour, duration: 2.hour),
902
- TimeFrame.new(min: time + shift, duration: 2.hour)
903
- ]
904
- end
905
- let(:expected) do
906
- [
907
- TimeFrame.new(min: frame.min + 1.hour,
908
- max: frame.max - 1.hour)
909
- ]
910
- end
911
- subject { frame.without(*arg) }
912
- it { should eq expected }
913
- end
914
- context 'and we have three frames in args overlaped by self' do
915
- context 'which are sorted' do
916
- let(:arg) do
917
- [
918
- TimeFrame.new(min: time + 1.hour, duration: 2.hour),
919
- TimeFrame.new(min: time + 4.hours, duration: 2.hour),
920
- TimeFrame.new(min: time + 7.hours, duration: 2.hour)
921
- ]
922
- end
923
- let(:expected) do
924
- [
925
- TimeFrame.new(min: time, max: time + 1.hour),
926
- TimeFrame.new(min: time + 3.hours, max: time + 4.hour),
927
- TimeFrame.new(min: time + 6.hours, max: time + 7.hours),
928
- TimeFrame.new(min: time + 9.hours, max: time + 10.hours)
929
- ]
930
- end
931
- subject { frame.without(*arg) }
932
- it { should eq expected }
933
- end
934
- context 'and they are unsorted' do
935
- let(:arg) do
936
- [
937
- TimeFrame.new(min: time + 4.hours, duration: 2.hour),
938
- TimeFrame.new(min: time + 1.hour, duration: 2.hour),
939
- TimeFrame.new(min: time + 7.hours, duration: 2.hour)
940
- ]
941
- end
942
- let(:expected) do
943
- [
944
- TimeFrame.new(min: time, max: time + 1.hour),
945
- TimeFrame.new(min: time + 3.hours, max: time + 4.hour),
946
- TimeFrame.new(min: time + 6.hours, max: time + 7.hours),
947
- TimeFrame.new(min: time + 9.hours, max: time + 10.hours)
948
- ]
949
- end
950
- subject { frame.without(*arg) }
951
- it { should eq expected }
952
- end
953
- end
954
- end
955
- end
956
- end
957
- end
958
-
959
- describe '.covering_time_frame_for' do
960
-
961
- context 'for an empty array' do
962
- subject { TimeFrame.covering_time_frame_for([]) }
963
- it { should be_nil }
964
- end
965
-
966
- context 'for a single time frame' do
967
- let(:frame) { TimeFrame.new(min: time, duration: 1.hour) }
968
- subject { TimeFrame.covering_time_frame_for([frame]) }
969
- it { should eq frame }
970
- end
971
-
972
- context 'for multiple time frames' do
973
- let(:frame1) { TimeFrame.new(min: time, duration: 2.hours) }
974
- let(:frame2) { frame1.shift_by(-1.hour) }
975
- let(:frame3) { frame1.shift_by(3.hours) }
976
- subject do
977
- TimeFrame.covering_time_frame_for([frame1, frame2, frame3])
978
- end
979
-
980
- describe '#min' do
981
- subject { super().min }
982
- it { should eq frame2.min }
983
- end
984
-
985
- describe '#max' do
986
- subject { super().max }
987
- it { should eq frame3.max }
988
- end
989
- end
990
- end
991
-
992
- describe '.each_overlap' do
993
-
994
- # Visualization of example input:
995
- #
996
- # array1: |---|-------| |-------|-----------|
997
- # array2: |-----------| |---| |---| |---|
998
- #
999
- # 0 1 2 3 4 5 6 7 8 9 10 11
1000
-
1001
- let(:array1) do
1002
- [
1003
- TimeFrame.new(min: time, max: time + 1.hour),
1004
- TimeFrame.new(min: time + 1.hour, max: time + 3.hours),
1005
- TimeFrame.new(min: time + 4.hours, max: time + 6.hours),
1006
- TimeFrame.new(min: time + 6.hours, max: time + 9.hours)
1007
- ]
1008
- end
1009
-
1010
- let(:array2) do
1011
- [
1012
- TimeFrame.new(min: time + 2.hours, max: time + 5.hour),
1013
- TimeFrame.new(min: time + 6.hour, max: time + 7.hours),
1014
- TimeFrame.new(min: time + 8.hours, max: time + 9.hours),
1015
- TimeFrame.new(min: time + 10.hours, max: time + 11.hours)
1016
- ]
1017
- end
1018
-
1019
- it 'yields the block for each overlap' do
1020
- overlaps = []
1021
- TimeFrame.each_overlap(array1, array2) { |a, b| overlaps << [a, b] }
1022
- expect(overlaps).to eq [
1023
- [array1[1], array2[0]],
1024
- [array1[2], array2[0]],
1025
- [array1[3], array2[1]],
1026
- [array1[3], array2[2]]
1027
- ]
1028
- end
1029
-
1030
- it 'still works when switching arguments' do
1031
- overlaps = []
1032
- TimeFrame.each_overlap(array2, array1) { |a, b| overlaps << [a, b] }
1033
- expect(overlaps).to eq [
1034
- [array2[0], array1[1]],
1035
- [array2[0], array1[2]],
1036
- [array2[1], array1[3]],
1037
- [array2[2], array1[3]]
1038
- ]
1039
- end
1040
-
1041
- it 'works if first array is empty' do
1042
- overlaps = []
1043
- TimeFrame.each_overlap([], array2) { |a, b| overlaps << [a, b] }
1044
- expect(overlaps).to be_empty
1045
- end
1046
-
1047
- it 'works if second array is empty' do
1048
- overlaps = []
1049
- TimeFrame.each_overlap(array1, []) { |a, b| overlaps << [a, b] }
1050
- expect(overlaps).to be_empty
1051
- end
1052
- end
1053
-
1054
- describe '#inspect' do
1055
- it 'works for a TimeFrame with same min and max' do
1056
- time = Time.now
1057
- expected = "#{time}..#{time}"
1058
- tr = TimeFrame.new(min: time, max: time)
1059
- actual = tr.inspect
1060
- expect(actual).to eq expected
1061
- end
1062
-
1063
- it 'works for a TimeFrame created with min and max' do
1064
- min = Time.now
1065
- max = min + 10.minutes
1066
- expected = "#{min}..#{max}"
1067
- tr = TimeFrame.new(min: min, max: max)
1068
- actual = tr.inspect
1069
- expect(actual).to eq expected
1070
- end
1071
-
1072
- it 'works for a TimeFrame created with min and duration' do
1073
- min = Time.now
1074
- max = min + 10.minutes
1075
- expected = "#{min}..#{max}"
1076
- tr = TimeFrame.new(min: min, duration: 10.minutes)
1077
- actual = tr.inspect
1078
- expect(actual).to eq expected
1079
- end
1080
- end
1081
- end