chronological 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/chronological.rb +5 -116
- data/lib/chronological/absolute_timeframe.rb +98 -0
- data/lib/chronological/base.rb +41 -0
- data/lib/chronological/relative_timeframe.rb +57 -0
- data/lib/chronological/version.rb +1 -1
- data/spec/{chronological_spec.rb → absolute_timeframe_spec.rb} +72 -218
- data/spec/base_spec.rb +230 -0
- data/spec/relative_timeframe_spec.rb +207 -0
- data/spec/spec_helper.rb +15 -2
- metadata +11 -4
data/spec/base_spec.rb
ADDED
@@ -0,0 +1,230 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class BaseChronologicable < ActiveRecord::Base
|
4
|
+
extend Chronological::Base
|
5
|
+
|
6
|
+
base_timeframe :start_date_field => :started_on,
|
7
|
+
:start_time_field => :started_at,
|
8
|
+
:end_date_field => :ended_on,
|
9
|
+
:end_time_field => :ended_at
|
10
|
+
|
11
|
+
private
|
12
|
+
def has_absolute_timeframe?
|
13
|
+
started_at.present? && ended_at.present?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe Chronological::Base do
|
18
|
+
let(:started_at) { nil }
|
19
|
+
let(:ended_at) { nil }
|
20
|
+
|
21
|
+
let(:chronologicable) do
|
22
|
+
BaseChronologicable.new(
|
23
|
+
:started_at => started_at,
|
24
|
+
:ended_at => ended_at
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#started_on' do
|
29
|
+
context 'when #started_at is set' do
|
30
|
+
context 'to a string' do
|
31
|
+
let(:started_at) { '2012-07-26 03:15:12' }
|
32
|
+
|
33
|
+
it 'properly converts the date' do
|
34
|
+
chronologicable.started_on.should eql Time.utc(2012, 7, 26, 3, 15, 12).to_date
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'to a date' do
|
39
|
+
let(:started_at) { Time.utc(2012, 7, 26, 3, 15, 12) }
|
40
|
+
|
41
|
+
it 'properly converts the date' do
|
42
|
+
chronologicable.started_on.should eql Time.utc(2012, 7, 26, 3, 15, 12).to_date
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'when #started_at is not set' do
|
48
|
+
let(:started_at) { nil }
|
49
|
+
|
50
|
+
it 'is nil' do
|
51
|
+
chronologicable.started_on.should be_nil
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#ended_on' do
|
57
|
+
context 'when #ended_at is set' do
|
58
|
+
context 'to a string' do
|
59
|
+
let(:ended_at) { '2012-07-26 03:15:12' }
|
60
|
+
|
61
|
+
it 'properly converts the date' do
|
62
|
+
chronologicable.ended_on.should eql Time.utc(2012, 7, 26, 3, 15, 12).to_date
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'to a date' do
|
67
|
+
let(:ended_at) { Time.utc(2012, 7, 26, 3, 15, 12) }
|
68
|
+
|
69
|
+
it 'properly converts the date' do
|
70
|
+
chronologicable.ended_on.should eql Time.utc(2012, 7, 26, 3, 15, 12).to_date
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'when #ended_at is not set' do
|
76
|
+
let(:ended_at) { nil }
|
77
|
+
|
78
|
+
it 'is nil' do
|
79
|
+
chronologicable.ended_on.should be_nil
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe '#duration' do
|
85
|
+
context 'when the chronologicable represents something with a duration' do
|
86
|
+
before { chronologicable.should_receive(:duration_in_seconds).any_number_of_times.and_return(6263) }
|
87
|
+
|
88
|
+
it 'is a hash with the correct hours' do
|
89
|
+
chronologicable.duration[:hours].should eql 1
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'is a hash with the correct minutes' do
|
93
|
+
chronologicable.duration[:minutes].should eql 44
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'is a hash with the correct seconds' do
|
97
|
+
chronologicable.duration[:seconds].should eql 23
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'when the chronologicable represents something with an even second time duration' do
|
102
|
+
before { chronologicable.should_receive(:duration_in_seconds).any_number_of_times.and_return(6240) }
|
103
|
+
|
104
|
+
it 'is a hash with the correct hours' do
|
105
|
+
chronologicable.duration[:hours].should eql 1
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'is a hash with the correct minutes' do
|
109
|
+
chronologicable.duration[:minutes].should eql 44
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'is a hash with the correct seconds' do
|
113
|
+
chronologicable.duration[:seconds].should eql 0
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'when the chronologicable represents something with an even minute time duration' do
|
118
|
+
before { chronologicable.should_receive(:duration_in_seconds).any_number_of_times.and_return(3600) }
|
119
|
+
|
120
|
+
it 'is a hash with the correct hours' do
|
121
|
+
chronologicable.duration[:hours].should eql 1
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'is a hash with the correct minutes' do
|
125
|
+
chronologicable.duration[:minutes].should eql 0
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'is a hash with the correct seconds' do
|
129
|
+
chronologicable.duration[:seconds].should eql 0
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context 'when the chronologicable represents something with a zero duration' do
|
134
|
+
before { chronologicable.should_receive(:duration_in_seconds).any_number_of_times.and_return(0) }
|
135
|
+
|
136
|
+
it 'is a hash with the correct hours' do
|
137
|
+
chronologicable.duration[:hours].should eql 0
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'is a hash with the correct minutes' do
|
141
|
+
chronologicable.duration[:minutes].should eql 0
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'is a hash with the correct seconds' do
|
145
|
+
chronologicable.duration[:seconds].should eql 0
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context 'when duration in seconds returns an empty value' do
|
150
|
+
before { chronologicable.should_receive(:duration_in_seconds).and_return(nil) }
|
151
|
+
|
152
|
+
it 'is an empty hash' do
|
153
|
+
chronologicable.duration.should eql Hash.new
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
describe '#in_progress?', :timecop => true do
|
159
|
+
let(:later) { Time.local(2012, 7, 26, 6, 0, 26) }
|
160
|
+
let(:now) { Time.local(2012, 7, 26, 6, 0, 25) }
|
161
|
+
let(:past) { Time.local(2012, 7, 26, 6, 0, 24) }
|
162
|
+
|
163
|
+
before { Timecop.freeze(now) }
|
164
|
+
|
165
|
+
context 'when it does not have an absolute timeframe' do
|
166
|
+
before { chronologicable.should_receive(:has_absolute_timeframe?).and_return(false) }
|
167
|
+
|
168
|
+
it 'is false' do
|
169
|
+
chronologicable.should_not be_in_progress
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
context 'when it has already started' do
|
174
|
+
let(:started_at) { past }
|
175
|
+
|
176
|
+
context 'and already ended' do
|
177
|
+
let(:ended_at) { past }
|
178
|
+
|
179
|
+
it 'is false' do
|
180
|
+
chronologicable.should_not be_in_progress
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
context 'and ends now' do
|
185
|
+
let(:ended_at) { now }
|
186
|
+
|
187
|
+
it 'is false' do
|
188
|
+
chronologicable.should_not be_in_progress
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
context 'and ends later' do
|
193
|
+
let(:ended_at) { later }
|
194
|
+
|
195
|
+
it 'is true' do
|
196
|
+
chronologicable.should be_in_progress
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
context 'when there is a chronologicable that starts now' do
|
202
|
+
let(:started_at) { now }
|
203
|
+
|
204
|
+
context 'and ends now' do
|
205
|
+
let(:ended_at) { now }
|
206
|
+
|
207
|
+
it 'is false' do
|
208
|
+
chronologicable.should_not be_in_progress
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
context 'and ends later' do
|
213
|
+
let(:ended_at) { later }
|
214
|
+
|
215
|
+
it 'is true' do
|
216
|
+
chronologicable.should be_in_progress
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
context 'when there is a chronologicable that has not yet started' do
|
222
|
+
let(:started_at) { later }
|
223
|
+
let(:ended_at) { later }
|
224
|
+
|
225
|
+
it 'is false' do
|
226
|
+
chronologicable.should_not be_in_progress
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
@@ -0,0 +1,207 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class RelativeChronologicable < ActiveRecord::Base
|
4
|
+
include Chronological::RelativeTimeframe
|
5
|
+
|
6
|
+
relative_timeframe :start => :starting_offset,
|
7
|
+
:end => :ending_offset,
|
8
|
+
:base_utc => :base_datetime_utc
|
9
|
+
end
|
10
|
+
|
11
|
+
describe Chronological::RelativeTimeframe do
|
12
|
+
let(:now) { Time.local(2012, 7, 26, 6, 0, 0) }
|
13
|
+
let(:base_time) { Time.local(2012, 7, 26, 6, 0, 30) }
|
14
|
+
|
15
|
+
before { Timecop.freeze(now) }
|
16
|
+
|
17
|
+
let(:chronologicable) do
|
18
|
+
RelativeChronologicable.create(
|
19
|
+
:starting_offset => starting_offset,
|
20
|
+
:ending_offset => ending_offset,
|
21
|
+
:base_datetime_utc => base_time)
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#started_at_utc' do
|
25
|
+
let(:ending_offset) { 'anything' }
|
26
|
+
|
27
|
+
context 'when the starting offset is set' do
|
28
|
+
let(:starting_offset) { 30 }
|
29
|
+
|
30
|
+
context 'but the base time is not set' do
|
31
|
+
let(:base_time) { nil }
|
32
|
+
|
33
|
+
it 'is nil' do
|
34
|
+
chronologicable.started_at_utc.should be_nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'and the base time is set' do
|
39
|
+
let(:base_time) { Time.local(2012, 7, 26, 6, 0, 30) }
|
40
|
+
|
41
|
+
it 'is the proper offset calculation' do
|
42
|
+
chronologicable.started_at_utc.should eql Time.local(2012, 7, 26, 6, 0, 0)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'when the starting offset is not set' do
|
48
|
+
let(:starting_offset) { nil }
|
49
|
+
|
50
|
+
it 'is nil' do
|
51
|
+
chronologicable.started_at_utc.should be_nil
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#ended_at_utc' do
|
57
|
+
let(:starting_offset) { 'anything' }
|
58
|
+
|
59
|
+
context 'when the ending offset is set' do
|
60
|
+
let(:ending_offset) { 30 }
|
61
|
+
|
62
|
+
context 'but the base time is not set' do
|
63
|
+
let(:base_time) { nil }
|
64
|
+
|
65
|
+
it 'is nil' do
|
66
|
+
chronologicable.ended_at_utc.should be_nil
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'and the base time is set' do
|
71
|
+
let(:base_time) { Time.local(2012, 7, 26, 6, 0, 30) }
|
72
|
+
|
73
|
+
it 'is the proper offset calculation' do
|
74
|
+
chronologicable.ended_at_utc.should eql Time.local(2012, 7, 26, 6, 0, 0)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'when the ending offset is not set' do
|
80
|
+
let(:ending_offset) { nil }
|
81
|
+
|
82
|
+
it 'is nil' do
|
83
|
+
chronologicable.ended_at_utc.should be_nil
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'when the base time is not set' do
|
89
|
+
let(:now) { Time.local(2012, 7, 26, 6, 0, 0) }
|
90
|
+
let(:base_time) { nil }
|
91
|
+
|
92
|
+
context 'but the starting offset is set' do
|
93
|
+
let(:starting_offset) { 30 }
|
94
|
+
|
95
|
+
context 'and the ending offset is set' do
|
96
|
+
let(:ending_offset) { 0 }
|
97
|
+
|
98
|
+
it 'is not scheduled' do
|
99
|
+
chronologicable.should_not be_scheduled
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'is partially scheduled' do
|
103
|
+
chronologicable.should be_partially_scheduled
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context 'and the ending offset is not set' do
|
108
|
+
let(:ending_offset) { nil }
|
109
|
+
|
110
|
+
it 'is not scheduled' do
|
111
|
+
chronologicable.should_not be_scheduled
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'is partially scheduled' do
|
115
|
+
chronologicable.should be_partially_scheduled
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context 'and the starting offset is not set' do
|
121
|
+
let(:starting_offset) { nil }
|
122
|
+
|
123
|
+
context 'but the ending offset is set' do
|
124
|
+
let(:ending_offset) { 0 }
|
125
|
+
|
126
|
+
it 'is not scheduled' do
|
127
|
+
chronologicable.should_not be_scheduled
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'is partially scheduled' do
|
131
|
+
chronologicable.should be_partially_scheduled
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context 'and neither of the offsets is set' do
|
137
|
+
let(:starting_offset) { nil }
|
138
|
+
let(:ending_offset) { nil }
|
139
|
+
|
140
|
+
it 'is not scheduled' do
|
141
|
+
chronologicable.should_not be_scheduled
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'is not partially scheduled' do
|
145
|
+
chronologicable.should_not be_partially_scheduled
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
context 'when the starting offset is not set' do
|
151
|
+
let(:now) { Time.local(2012, 7, 26, 6, 0, 0) }
|
152
|
+
let(:starting_offset) { nil }
|
153
|
+
|
154
|
+
context 'and the ending offset is not set' do
|
155
|
+
let(:ending_offset) { nil }
|
156
|
+
|
157
|
+
it 'is not scheduled' do
|
158
|
+
chronologicable.should_not be_scheduled
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'is partially scheduled' do
|
162
|
+
chronologicable.should be_partially_scheduled
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context 'and the ending offset is set' do
|
167
|
+
let(:ending_offset) { 0 }
|
168
|
+
|
169
|
+
it 'is not scheduled' do
|
170
|
+
chronologicable.should_not be_scheduled
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'is partially scheduled' do
|
174
|
+
chronologicable.should be_partially_scheduled
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
context 'when the starting offset is set' do
|
180
|
+
let(:now) { Time.local(2012, 7, 26, 6, 0, 0) }
|
181
|
+
let(:starting_offset) { 30 }
|
182
|
+
|
183
|
+
context 'and the ending offset is not set' do
|
184
|
+
let(:ending_offset) { nil }
|
185
|
+
|
186
|
+
it 'is not scheduled' do
|
187
|
+
chronologicable.should_not be_scheduled
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'is partially scheduled' do
|
191
|
+
chronologicable.should be_partially_scheduled
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
context 'and the ending offset is set' do
|
196
|
+
let(:ending_offset) { 0 }
|
197
|
+
|
198
|
+
it 'is scheduled' do
|
199
|
+
chronologicable.should be_scheduled
|
200
|
+
end
|
201
|
+
|
202
|
+
it 'is partially scheduled' do
|
203
|
+
chronologicable.should be_partially_scheduled
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -16,7 +16,18 @@ RSpec.configure do |config|
|
|
16
16
|
|
17
17
|
class SetupTests < ActiveRecord::Migration
|
18
18
|
def up
|
19
|
-
create_table :
|
19
|
+
create_table :base_chronologicables do |t|
|
20
|
+
t.datetime :started_at
|
21
|
+
t.datetime :ended_at
|
22
|
+
end
|
23
|
+
|
24
|
+
create_table :relative_chronologicables do |t|
|
25
|
+
t.integer :starting_offset
|
26
|
+
t.integer :ending_offset
|
27
|
+
t.datetime :base_datetime_utc
|
28
|
+
end
|
29
|
+
|
30
|
+
create_table :absolute_chronologicables do |t|
|
20
31
|
t.datetime :started_at_utc
|
21
32
|
t.datetime :ended_at_utc
|
22
33
|
end
|
@@ -33,7 +44,9 @@ RSpec.configure do |config|
|
|
33
44
|
end
|
34
45
|
|
35
46
|
config.before(:each) do
|
36
|
-
ActiveRecord::Base.connection.execute 'DELETE FROM
|
47
|
+
ActiveRecord::Base.connection.execute 'DELETE FROM relative_chronologicables'
|
48
|
+
ActiveRecord::Base.connection.execute 'DELETE FROM absolute_chronologicables'
|
49
|
+
ActiveRecord::Base.connection.execute 'DELETE FROM chronologicable_with_time_zones'
|
37
50
|
end
|
38
51
|
|
39
52
|
config.after(:suite) do
|