time_frame 0.0.6 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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