chronological 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,3 @@
1
1
  module Chronological
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
data/lib/chronological.rb CHANGED
@@ -1,98 +1,113 @@
1
1
  module Chronological
2
2
  module ClassMethods
3
- ###
4
- # Scopes
5
- #
6
- def by_date
7
- order "#{table_name}.started_at_utc ASC, #{table_name}.ended_at_utc ASC"
8
- end
9
-
10
- def by_date_reversed
11
- order "#{table_name}.started_at_utc DESC, #{table_name}.ended_at_utc DESC"
12
- end
13
-
14
- def expired
15
- where('ended_at_utc < :now', :now => Time.now.utc)
16
- end
17
-
18
- def current
19
- where('ended_at_utc > :now', :now => Time.now.utc)
20
- end
21
-
22
- def in_progress
23
- where('started_at_utc <= :now AND ended_at_utc > :now', :now => Time.now.utc)
24
- end
25
-
26
- alias active in_progress
27
-
28
- def in_progress?
29
- in_progress.any?
30
- end
31
-
32
- alias active? in_progress?
33
-
34
- def started
35
- where("started_at_utc <= :now", :now => Time.now.utc)
3
+ def chronological(options = {})
4
+ start_field = options[:start_utc] || options[:start]
5
+ end_field = options[:end_utc] || options[:end]
6
+ time_zone = options[:time_zone]
7
+ start_field_is_utc = options.has_key? :start_utc
8
+ end_field_is_utc = options.has_key? :end_utc
9
+ start_field_utc_suffix = start_field_is_utc ? '_utc' : ''
10
+ end_field_utc_suffix = end_field_is_utc ? '_utc' : ''
11
+
12
+ define_method(:started_at_utc_date) do
13
+ return nil unless send(start_field).respond_to? :to_date
14
+
15
+ send(start_field).to_date
16
+ end
17
+
18
+ define_method(:ended_at_utc_date) do
19
+ return nil unless send(end_field).respond_to? :to_date
20
+
21
+ send(end_field).to_date
22
+ end
23
+
24
+ define_method(:in_progress?) do
25
+ return false unless scheduled?
26
+
27
+ (send(start_field) <= Time.now.utc) && send(end_field).future?
28
+ end
29
+
30
+ define_method(:inactive?) do
31
+ !active?
32
+ end
33
+
34
+ define_method(:scheduled?) do
35
+ optional_time_zone = !options[:time_zone].nil? ? send(time_zone) : true
36
+
37
+ send(start_field).present? && send(end_field).present? && optional_time_zone
38
+ end
39
+
40
+ define_method(:partially_scheduled?) do
41
+ optional_time_zone = !options[:time_zone].nil? ? send(time_zone) : false
42
+
43
+ send(start_field).present? || send(end_field).present? || optional_time_zone
44
+ end
45
+
46
+ define_method(:duration) do
47
+ hours = (duration_in_seconds / 3600).to_i
48
+ minutes = ((duration_in_seconds % 3600) / 60).to_i
49
+ seconds = (duration_in_seconds % 60).to_i
50
+
51
+ { :hours => hours, :minutes => minutes, :seconds => seconds }
52
+ end
53
+
54
+ ###
55
+ # Scopes
56
+ #
57
+ self.class.send(:define_method, :by_date) do
58
+ order "#{table_name}.#{start_field} ASC, #{table_name}.#{end_field} ASC"
59
+ end
60
+
61
+ self.class.send(:define_method, :by_date_reversed) do
62
+ order "#{table_name}.#{start_field} DESC, #{table_name}.#{end_field} DESC"
63
+ end
64
+
65
+ self.class.send(:define_method, :expired) do
66
+ where("#{end_field} <= :now", :now => Time.now.utc)
67
+ end
68
+
69
+ self.class.send(:define_method, :current) do
70
+ where("#{end_field} > :now", :now => Time.now.utc)
71
+ end
72
+
73
+ self.class.send(:define_method, :in_progress) do
74
+ where("#{start_field} <= :now AND #{end_field} > :now", :now => Time.now.utc)
75
+ end
76
+
77
+ self.class.send(:define_method, :started) do
78
+ where("#{start_field} <= :now", :now => Time.now.utc)
79
+ end
80
+
81
+ self.class.send(:define_method, :in_progress?) do
82
+ in_progress.any?
83
+ end
84
+
85
+ instance_eval do
86
+ alias active? in_progress?
87
+ alias active in_progress
88
+ end
89
+
90
+ ###
91
+ # Aliases
92
+ #
93
+ # Aliasing date methods to make code more readable
94
+ class_eval do
95
+ alias_attribute :"starts_at#{start_field_utc_suffix}", start_field.to_sym
96
+ alias_attribute :"starting_at#{start_field_utc_suffix}", start_field.to_sym
97
+ alias_attribute :"ends_at#{start_field_utc_suffix}", end_field.to_sym
98
+ alias_attribute :"ending_at#{start_field_utc_suffix}", end_field.to_sym
99
+
100
+ alias active? in_progress?
101
+ end
102
+
103
+ private
104
+ define_method(:duration_in_seconds) do
105
+ (send(end_field) - send(start_field))
106
+ end
36
107
  end
37
108
  end
38
109
 
39
110
  def self.included(base)
40
111
  base.extend ClassMethods
41
-
42
- ###
43
- # Aliases
44
- #
45
- # Aliasing date methods to make code more readable
46
-
47
- base.instance_eval <<-EVALING
48
- alias_attribute :starts_at_utc, :started_at_utc
49
- alias_attribute :starting_at_utc, :started_at_utc
50
- alias_attribute :ends_at_utc, :ended_at_utc
51
- alias_attribute :ending_at_utc, :ended_at_utc
52
- EVALING
53
- end
54
-
55
- def started_at_utc_date
56
- return nil unless started_at_utc.respond_to? :to_date
57
-
58
- started_at_utc.to_date
59
- end
60
-
61
- def ended_at_utc_date
62
- return nil unless ended_at_utc.respond_to? :to_date
63
-
64
- ended_at_utc.to_date
65
- end
66
-
67
- def in_progress?
68
- return false unless scheduled?
69
-
70
- (started_at_utc <= Time.now.utc) && ended_at_utc.future?
71
- end
72
-
73
- alias active? in_progress?
74
-
75
- def inactive?
76
- !active?
77
- end
78
-
79
- def scheduled?
80
- started_at_utc.present? && ended_at_utc.present?
81
- end
82
-
83
- def partially_scheduled?
84
- started_at_utc.present? || ended_at_utc.present?
85
- end
86
-
87
- def duration
88
- hours = (duration_in_minutes / 60).to_int
89
- minutes = (duration_in_minutes % 60).to_int
90
-
91
- { :hours => hours, :minutes => minutes }
92
- end
93
-
94
- private
95
- def duration_in_minutes
96
- @duration_in_minutes ||= (ended_at_utc - started_at_utc) / 60
97
112
  end
98
113
  end
@@ -2,12 +2,23 @@ require 'spec_helper'
2
2
 
3
3
  class Chronologicable < ActiveRecord::Base
4
4
  include Chronological
5
+
6
+ chronological :start_utc => :started_at_utc,
7
+ :end_utc => :ended_at_utc
5
8
  end
6
9
 
7
- describe Chronological do
8
- let(:later) { Time.utc(2012, 7, 26, 6, 0, 26) }
9
- let(:now) { Time.utc(2012, 7, 26, 6, 0, 25) }
10
- let(:past) { Time.utc(2012, 7, 26, 6, 0, 24) }
10
+ class ChronologicableWithTimeZone < ActiveRecord::Base
11
+ include Chronological
12
+
13
+ chronological :start_utc => :started_at_utc,
14
+ :end_utc => :ended_at_utc,
15
+ :time_zone => :time_zone
16
+ end
17
+
18
+ describe Chronological, :timecop => true do
19
+ let(:later) { Time.local(2012, 7, 26, 6, 0, 26) }
20
+ let(:now) { Time.local(2012, 7, 26, 6, 0, 25) }
21
+ let(:past) { Time.local(2012, 7, 26, 6, 0, 24) }
11
22
 
12
23
  before { Timecop.freeze(now) }
13
24
 
@@ -17,10 +28,107 @@ describe Chronological do
17
28
  :ended_at_utc => end_time)
18
29
  end
19
30
 
31
+ let(:chronologicable_without_enabled_time_zone) do
32
+ Chronologicable.new(
33
+ :started_at_utc => start_time,
34
+ :ended_at_utc => end_time)
35
+ end
36
+
37
+ let(:chronologicable_with_enabled_time_zone) do
38
+ ChronologicableWithTimeZone.new(
39
+ :started_at_utc => start_time,
40
+ :ended_at_utc => end_time,
41
+ :time_zone => time_zone)
42
+ end
43
+
20
44
  it { Chronologicable.new.respond_to?(:starts_at_utc).should be_true }
21
45
  it { Chronologicable.new.respond_to?(:starting_at_utc).should be_true }
22
46
  it { Chronologicable.new.respond_to?(:ends_at_utc).should be_true }
23
47
  it { Chronologicable.new.respond_to?(:ending_at_utc).should be_true }
48
+ it { Chronologicable.new.respond_to?(:active?).should be_true }
49
+
50
+ it { Chronologicable.respond_to?(:active?).should be_true }
51
+ it { Chronologicable.respond_to?(:active).should be_true }
52
+
53
+ context 'when there are two chronologicables that start at the same time' do
54
+ context 'but end at different times' do
55
+ let!(:chronologicable_1) { Chronologicable.create :started_at_utc => past, :ended_at_utc => past }
56
+ let!(:chronologicable_2) { Chronologicable.create :started_at_utc => past, :ended_at_utc => now }
57
+
58
+ describe '.by_date' do
59
+ it 'properly sorts them' do
60
+ Chronologicable.by_date.first.should eql chronologicable_1
61
+ Chronologicable.by_date.last.should eql chronologicable_2
62
+ end
63
+ end
64
+
65
+ describe '.by_date_reversed' do
66
+ it 'sorts them backwards by the start date' do
67
+ Chronologicable.by_date_reversed.first.should eql chronologicable_2
68
+ Chronologicable.by_date_reversed.last.should eql chronologicable_1
69
+ end
70
+ end
71
+ end
72
+
73
+ context 'and end at the same time' do
74
+ let!(:chronologicable_1) { Chronologicable.create :started_at_utc => past, :ended_at_utc => now }
75
+ let!(:chronologicable_2) { Chronologicable.create :started_at_utc => past, :ended_at_utc => now }
76
+
77
+ describe '.by_date' do
78
+ it 'does not matter what order they are in as long as they are all there' do
79
+ Chronologicable.by_date.should include chronologicable_1
80
+ Chronologicable.by_date.should include chronologicable_2
81
+ end
82
+ end
83
+
84
+ describe '.by_date_reversed' do
85
+ it 'does not matter what order they are in as long as they are all there' do
86
+ Chronologicable.by_date.should include chronologicable_1
87
+ Chronologicable.by_date.should include chronologicable_2
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ context 'when there are two chronologicables that start at different times' do
94
+ context 'and end at different times' do
95
+ let!(:chronologicable_1) { Chronologicable.create :started_at_utc => past, :ended_at_utc => now }
96
+ let!(:chronologicable_2) { Chronologicable.create :started_at_utc => now, :ended_at_utc => later }
97
+
98
+ describe '.by_date' do
99
+ it 'sorts them by the start date' do
100
+ Chronologicable.by_date.first.should eql chronologicable_1
101
+ Chronologicable.by_date.last.should eql chronologicable_2
102
+ end
103
+ end
104
+
105
+ describe '.by_date_reversed' do
106
+ it 'sorts them backwards by the start date' do
107
+ Chronologicable.by_date_reversed.first.should eql chronologicable_2
108
+ Chronologicable.by_date_reversed.last.should eql chronologicable_1
109
+ end
110
+ end
111
+ end
112
+
113
+ context 'but end at the same time' do
114
+ let!(:chronologicable_1) { Chronologicable.create :started_at_utc => past, :ended_at_utc => later }
115
+ let!(:chronologicable_2) { Chronologicable.create :started_at_utc => now, :ended_at_utc => later }
116
+
117
+ describe '.by_date' do
118
+ it 'sorts them by the start date' do
119
+ Chronologicable.by_date.first.should eql chronologicable_1
120
+ Chronologicable.by_date.last.should eql chronologicable_2
121
+ end
122
+ end
123
+
124
+ describe '.by_date_reversed' do
125
+ it 'sorts them backwards by the start date' do
126
+ Chronologicable.by_date_reversed.first.should eql chronologicable_2
127
+ Chronologicable.by_date_reversed.last.should eql chronologicable_1
128
+ end
129
+ end
130
+ end
131
+ end
24
132
 
25
133
  describe '#started_at_utc_date' do
26
134
  context 'when the date field is set to a string' do
@@ -68,31 +176,79 @@ describe Chronological do
68
176
  context 'but no end time is set' do
69
177
  let(:end_time) { nil }
70
178
 
71
- describe '#scheduled?' do
72
- it 'is false' do
73
- chronologicable.should_not be_scheduled
179
+ context 'and no time zone is set' do
180
+ let(:time_zone) { nil }
181
+
182
+ describe '#scheduled?' do
183
+ it 'is correct' do
184
+ chronologicable_without_enabled_time_zone.should_not be_scheduled
185
+ chronologicable_with_enabled_time_zone.should_not be_scheduled
186
+ end
187
+ end
188
+
189
+ describe '#partially_scheduled?' do
190
+ it 'is correct' do
191
+ chronologicable_without_enabled_time_zone.should be_partially_scheduled
192
+ chronologicable_with_enabled_time_zone.should be_partially_scheduled
193
+ end
74
194
  end
75
195
  end
76
196
 
77
- describe '#partially_scheduled?' do
78
- it 'is true' do
79
- chronologicable.should be_partially_scheduled
197
+ context 'and a time zone is set' do
198
+ let(:time_zone) { ActiveSupport::TimeZone.new('Alaska') }
199
+
200
+ describe '#scheduled?' do
201
+ it 'is correct' do
202
+ chronologicable_without_enabled_time_zone.should_not be_scheduled
203
+ chronologicable_with_enabled_time_zone.should_not be_scheduled
204
+ end
205
+ end
206
+
207
+ describe '#partially_scheduled?' do
208
+ it 'is correct' do
209
+ chronologicable_without_enabled_time_zone.should be_partially_scheduled
210
+ chronologicable_with_enabled_time_zone.should be_partially_scheduled
211
+ end
80
212
  end
81
213
  end
82
214
  end
83
215
 
84
- context 'and an end time is set' do
216
+ context 'an end time is set' do
85
217
  let(:end_time) { Time.now }
86
218
 
87
- describe '#scheduled?' do
88
- it 'is true' do
89
- chronologicable.should be_scheduled
219
+ context 'but no time zone is set' do
220
+ let(:time_zone) { nil }
221
+
222
+ describe '#scheduled?' do
223
+ it 'is correct' do
224
+ chronologicable_without_enabled_time_zone.should be_scheduled
225
+ chronologicable_with_enabled_time_zone.should_not be_scheduled
226
+ end
227
+ end
228
+
229
+ describe '#partially_scheduled?' do
230
+ it 'is correct' do
231
+ chronologicable_without_enabled_time_zone.should be_partially_scheduled
232
+ chronologicable_with_enabled_time_zone.should be_partially_scheduled
233
+ end
90
234
  end
91
235
  end
92
236
 
93
- describe '#partially_scheduled?' do
94
- it 'is true' do
95
- chronologicable.should be_partially_scheduled
237
+ context 'and a time zone is set' do
238
+ let(:time_zone) { ActiveSupport::TimeZone.new('Alaska') }
239
+
240
+ describe '#scheduled?' do
241
+ it 'is correct' do
242
+ chronologicable_without_enabled_time_zone.should be_scheduled
243
+ chronologicable_with_enabled_time_zone.should be_scheduled
244
+ end
245
+ end
246
+
247
+ describe '#partially_scheduled?' do
248
+ it 'is correct' do
249
+ chronologicable_without_enabled_time_zone.should be_partially_scheduled
250
+ chronologicable_with_enabled_time_zone.should be_partially_scheduled
251
+ end
96
252
  end
97
253
  end
98
254
  end
@@ -112,7 +268,43 @@ describe Chronological do
112
268
 
113
269
  describe '#partially_scheduled?' do
114
270
  it 'is true' do
115
- chronologicable.should be_partially_scheduled
271
+ chronologicable.should be_partially_scheduled
272
+ end
273
+ end
274
+
275
+ context 'but no time zone is set' do
276
+ let(:time_zone) { nil }
277
+
278
+ describe '#scheduled?' do
279
+ it 'is correct' do
280
+ chronologicable_without_enabled_time_zone.should_not be_scheduled
281
+ chronologicable_with_enabled_time_zone.should_not be_scheduled
282
+ end
283
+ end
284
+
285
+ describe '#partially_scheduled?' do
286
+ it 'is correct' do
287
+ chronologicable_without_enabled_time_zone.should be_partially_scheduled
288
+ chronologicable_with_enabled_time_zone.should be_partially_scheduled
289
+ end
290
+ end
291
+ end
292
+
293
+ context 'and a time zone is set' do
294
+ let(:time_zone) { ActiveSupport::TimeZone.new('Alaska') }
295
+
296
+ describe '#scheduled?' do
297
+ it 'is correct' do
298
+ chronologicable_without_enabled_time_zone.should_not be_scheduled
299
+ chronologicable_with_enabled_time_zone.should_not be_scheduled
300
+ end
301
+ end
302
+
303
+ describe '#partially_scheduled?' do
304
+ it 'is correct' do
305
+ chronologicable_without_enabled_time_zone.should be_partially_scheduled
306
+ chronologicable_with_enabled_time_zone.should be_partially_scheduled
307
+ end
116
308
  end
117
309
  end
118
310
  end
@@ -146,6 +338,37 @@ describe Chronological do
146
338
  chronologicable.should_not be_in_progress
147
339
  end
148
340
  end
341
+
342
+ describe '.in_progress?' do
343
+ it 'is false' do
344
+ chronologicable
345
+ Chronologicable.should_not be_in_progress
346
+ end
347
+ end
348
+
349
+ describe '.expired' do
350
+ it 'includes that chronologicable' do
351
+ Chronologicable.expired.should include chronologicable
352
+ end
353
+ end
354
+
355
+ describe '.started' do
356
+ it 'includes that chronologicable' do
357
+ Chronologicable.started.should include chronologicable
358
+ end
359
+ end
360
+
361
+ describe '.current' do
362
+ it 'does not include that chronologicable' do
363
+ Chronologicable.current.should_not include chronologicable
364
+ end
365
+ end
366
+
367
+ describe '.in_progress' do
368
+ it 'does not include that chronologicable' do
369
+ Chronologicable.in_progress.should_not include chronologicable
370
+ end
371
+ end
149
372
  end
150
373
 
151
374
  context 'and ends now' do
@@ -156,6 +379,37 @@ describe Chronological do
156
379
  chronologicable.should_not be_in_progress
157
380
  end
158
381
  end
382
+
383
+ describe '.in_progress?' do
384
+ it 'is false' do
385
+ chronologicable
386
+ Chronologicable.should_not be_in_progress
387
+ end
388
+ end
389
+
390
+ describe '.expired' do
391
+ it 'does include that chronologicable' do
392
+ Chronologicable.expired.should include chronologicable
393
+ end
394
+ end
395
+
396
+ describe '.started' do
397
+ it 'includes that chronologicable' do
398
+ Chronologicable.started.should include chronologicable
399
+ end
400
+ end
401
+
402
+ describe '.current' do
403
+ it 'does not include that chronologicable' do
404
+ Chronologicable.current.should_not include chronologicable
405
+ end
406
+ end
407
+
408
+ describe '.in_progress' do
409
+ it 'does not include that chronologicable' do
410
+ Chronologicable.in_progress.should_not include chronologicable
411
+ end
412
+ end
159
413
  end
160
414
 
161
415
  context 'and ends later' do
@@ -163,7 +417,38 @@ describe Chronological do
163
417
 
164
418
  describe '#in_progress?' do
165
419
  it 'is true' do
166
- chronologicable.should be_in_progress
420
+ chronologicable.should be_in_progress
421
+ end
422
+ end
423
+
424
+ describe '.in_progress?' do
425
+ it 'is true' do
426
+ chronologicable
427
+ Chronologicable.should be_in_progress
428
+ end
429
+ end
430
+
431
+ describe '.expired' do
432
+ it 'does not include that chronologicable' do
433
+ Chronologicable.expired.should_not include chronologicable
434
+ end
435
+ end
436
+
437
+ describe '.started' do
438
+ it 'includes that chronologicable' do
439
+ Chronologicable.started.should include chronologicable
440
+ end
441
+ end
442
+
443
+ describe '.current' do
444
+ it 'includes that chronologicable' do
445
+ Chronologicable.current.should include chronologicable
446
+ end
447
+ end
448
+
449
+ describe '.in_progress' do
450
+ it 'includes that chronologicable' do
451
+ Chronologicable.in_progress.should include chronologicable
167
452
  end
168
453
  end
169
454
  end
@@ -180,6 +465,37 @@ describe Chronological do
180
465
  chronologicable.should_not be_in_progress
181
466
  end
182
467
  end
468
+
469
+ describe '.in_progress?' do
470
+ it 'is false' do
471
+ chronologicable
472
+ Chronologicable.should_not be_in_progress
473
+ end
474
+ end
475
+
476
+ describe '.expired' do
477
+ it 'does include that chronologicable' do
478
+ Chronologicable.expired.should include chronologicable
479
+ end
480
+ end
481
+
482
+ describe '.started' do
483
+ it 'includes that chronologicable' do
484
+ Chronologicable.started.should include chronologicable
485
+ end
486
+ end
487
+
488
+ describe '.current' do
489
+ it 'does not include that chronologicable' do
490
+ Chronologicable.current.should_not include chronologicable
491
+ end
492
+ end
493
+
494
+ describe '.in_progress' do
495
+ it 'does not include that chronologicable' do
496
+ Chronologicable.in_progress.should_not include chronologicable
497
+ end
498
+ end
183
499
  end
184
500
 
185
501
  context 'and ends later' do
@@ -187,7 +503,38 @@ describe Chronological do
187
503
 
188
504
  describe '#in_progress?' do
189
505
  it 'is true' do
190
- chronologicable.should be_in_progress
506
+ chronologicable.should be_in_progress
507
+ end
508
+ end
509
+
510
+ describe '.in_progress?' do
511
+ it 'is true' do
512
+ chronologicable
513
+ Chronologicable.should be_in_progress
514
+ end
515
+ end
516
+
517
+ describe '.expired' do
518
+ it 'does not include that chronologicable' do
519
+ Chronologicable.expired.should_not include chronologicable
520
+ end
521
+ end
522
+
523
+ describe '.started' do
524
+ it 'includes that chronologicable' do
525
+ Chronologicable.started.should include chronologicable
526
+ end
527
+ end
528
+
529
+ describe '.current' do
530
+ it 'includes that chronologicable' do
531
+ Chronologicable.current.should include chronologicable
532
+ end
533
+ end
534
+
535
+ describe '.in_progress' do
536
+ it 'includes that chronologicable' do
537
+ Chronologicable.in_progress.should include chronologicable
191
538
  end
192
539
  end
193
540
  end
@@ -202,5 +549,106 @@ describe Chronological do
202
549
  chronologicable.should_not be_in_progress
203
550
  end
204
551
  end
552
+
553
+ describe '.in_progress?' do
554
+ it 'is false' do
555
+ chronologicable
556
+ Chronologicable.should_not be_in_progress
557
+ end
558
+ end
559
+
560
+ describe '.expired' do
561
+ it 'does not include that chronologicable' do
562
+ Chronologicable.expired.should_not include chronologicable
563
+ end
564
+ end
565
+
566
+ describe '.started' do
567
+ it 'does not include that chronologicable' do
568
+ Chronologicable.started.should_not include chronologicable
569
+ end
570
+ end
571
+
572
+ describe '.current' do
573
+ it 'includes that chronologicable' do
574
+ Chronologicable.current.should include chronologicable
575
+ end
576
+ end
577
+
578
+ describe '.in_progress' do
579
+ it 'does not include that chronologicable' do
580
+ Chronologicable.in_progress.should_not include chronologicable
581
+ end
582
+ end
583
+ end
584
+
585
+ describe '#duration' do
586
+ context 'when the chronologicable represents something with a complex time duration' do
587
+ let(:start_time) { Time.local(2012, 7, 26, 14, 13, 16) }
588
+ let(:end_time) { Time.local(2012, 7, 26, 15, 57, 39) }
589
+
590
+ it 'is a hash with the correct hours' do
591
+ chronologicable.duration[:hours].should eql 1
592
+ end
593
+
594
+ it 'is a hash with the correct minutes' do
595
+ chronologicable.duration[:minutes].should eql 44
596
+ end
597
+
598
+ it 'is a hash with the correct seconds' do
599
+ chronologicable.duration[:seconds].should eql 23
600
+ end
601
+ end
602
+
603
+ context 'when the chronologicable represents something with an even second time duration' do
604
+ let(:start_time) { Time.local(2012, 7, 26, 14, 13, 16) }
605
+ let(:end_time) { Time.local(2012, 7, 26, 15, 57, 16) }
606
+
607
+ it 'is a hash with the correct hours' do
608
+ chronologicable.duration[:hours].should eql 1
609
+ end
610
+
611
+ it 'is a hash with the correct minutes' do
612
+ chronologicable.duration[:minutes].should eql 44
613
+ end
614
+
615
+ it 'is a hash with the correct seconds' do
616
+ chronologicable.duration[:seconds].should eql 0
617
+ end
618
+ end
619
+
620
+ context 'when the chronologicable represents something with an even minute time duration' do
621
+ let(:start_time) { Time.local(2012, 7, 26, 14, 13, 16) }
622
+ let(:end_time) { Time.local(2012, 7, 26, 15, 13, 16) }
623
+
624
+ it 'is a hash with the correct hours' do
625
+ chronologicable.duration[:hours].should eql 1
626
+ end
627
+
628
+ it 'is a hash with the correct minutes' do
629
+ chronologicable.duration[:minutes].should eql 0
630
+ end
631
+
632
+ it 'is a hash with the correct seconds' do
633
+ chronologicable.duration[:seconds].should eql 0
634
+ end
635
+ end
636
+
637
+ context 'when the chronologicable represents something with a zero duration' do
638
+ let(:start_time) { Time.local(2012, 7, 26, 14, 13, 16) }
639
+ let(:end_time) { Time.local(2012, 7, 26, 14, 13, 16) }
640
+
641
+ it 'is a hash with the correct hours' do
642
+ chronologicable.duration[:hours].should eql 0
643
+ end
644
+
645
+ it 'is a hash with the correct minutes' do
646
+ chronologicable.duration[:minutes].should eql 0
647
+ end
648
+
649
+ it 'is a hash with the correct seconds' do
650
+ chronologicable.duration[:seconds].should eql 0
651
+ end
652
+ end
205
653
  end
206
654
  end
data/spec/spec_helper.rb CHANGED
@@ -20,12 +20,22 @@ RSpec.configure do |config|
20
20
  t.datetime :started_at_utc
21
21
  t.datetime :ended_at_utc
22
22
  end
23
+
24
+ create_table :chronologicable_with_time_zones do |t|
25
+ t.datetime :started_at_utc
26
+ t.datetime :ended_at_utc
27
+ t.string :time_zone
28
+ end
23
29
  end
24
30
  end
25
31
 
26
32
  SetupTests.new.migrate(:up)
27
33
  end
28
34
 
35
+ config.before(:each) do
36
+ ActiveRecord::Base.connection.execute 'DELETE FROM chronologicables'
37
+ end
38
+
29
39
  config.after(:all) do
30
40
  `rm -f ./tmp/test.db`
31
41
  end
@@ -0,0 +1,5 @@
1
+ RSpec.configure do |config|
2
+ config.after(:each, :timecop => true) do
3
+ Timecop.return
4
+ end
5
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chronological
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-10-05 00:00:00.000000000 Z
13
+ date: 2012-10-06 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec
@@ -173,6 +173,7 @@ files:
173
173
  - spec/spec_helper.rb
174
174
  - spec/support/focused.rb
175
175
  - spec/support/pending.rb
176
+ - spec/support/timecop.rb
176
177
  homepage: https://github.com/chirrpy/chronological
177
178
  licenses: []
178
179
  post_install_message:
@@ -203,3 +204,4 @@ test_files:
203
204
  - spec/spec_helper.rb
204
205
  - spec/support/focused.rb
205
206
  - spec/support/pending.rb
207
+ - spec/support/timecop.rb