chronological 0.0.2 → 0.0.3

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.
@@ -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