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.
- data/lib/chronological/version.rb +1 -1
- data/lib/chronological.rb +104 -89
- data/spec/chronological_spec.rb +468 -20
- data/spec/spec_helper.rb +10 -0
- data/spec/support/timecop.rb +5 -0
- metadata +4 -2
data/lib/chronological.rb
CHANGED
@@ -1,98 +1,113 @@
|
|
1
1
|
module Chronological
|
2
2
|
module ClassMethods
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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
|
data/spec/chronological_spec.rb
CHANGED
@@ -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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
72
|
-
|
73
|
-
|
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
|
-
|
78
|
-
|
79
|
-
|
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 '
|
216
|
+
context 'an end time is set' do
|
85
217
|
let(:end_time) { Time.now }
|
86
218
|
|
87
|
-
|
88
|
-
|
89
|
-
|
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
|
-
|
94
|
-
|
95
|
-
|
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
|
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
|
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
|
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
|
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.
|
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-
|
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
|