chronological 0.0.9 → 1.0.0beta1
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/README.md +321 -17
- data/lib/chronological/errors.rb +3 -0
- data/lib/chronological/strategies/absolute.rb +44 -0
- data/lib/chronological/strategies/base.rb +82 -0
- data/lib/chronological/strategies/relative.rb +68 -0
- data/lib/chronological/strategies.rb +3 -0
- data/lib/chronological/strategy_resolver.rb +97 -0
- data/lib/chronological/version.rb +1 -1
- data/lib/chronological.rb +93 -3
- data/spec/chronological_spec.rb +33 -0
- data/spec/spec_helper.rb +1 -47
- data/spec/{absolute_timeframe_spec.rb → strategies/absolute_spec.rb} +120 -83
- data/spec/strategies/base_spec.rb +296 -0
- data/spec/{relative_timeframe_spec.rb → strategies/relative_spec.rb} +212 -16
- data/spec/strategy_resolver_spec.rb +56 -0
- data/spec/support/active_record.rb +47 -0
- metadata +26 -17
- data/lib/chronological/absolute_timeframe.rb +0 -98
- data/lib/chronological/base.rb +0 -41
- data/lib/chronological/relative_timeframe.rb +0 -96
- data/spec/base_spec.rb +0 -230
@@ -0,0 +1,296 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
describe Chronological::BaseStrategy do
|
5
|
+
let(:strategy) { Chronological::BaseStrategy.new(field_names) }
|
6
|
+
let(:chrono) { OpenStruct.new(fields) }
|
7
|
+
let(:fields) { nil }
|
8
|
+
let(:field_names) do
|
9
|
+
{ starting_time: :start_time,
|
10
|
+
ending_time: :end_time }
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#starting_date' do
|
14
|
+
context 'when working with a date/time' do
|
15
|
+
let(:fields) { { start_time: Time.utc(2012, 7, 26, 7, 12, 0) } }
|
16
|
+
|
17
|
+
it 'converts it to a date only' do
|
18
|
+
strategy.starting_date(chrono).should eql Time.utc(2012, 7, 26, 7, 12, 0).to_date
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'when working with a string' do
|
23
|
+
let(:fields) { { start_time: '2012-07-26 03:15:12' } }
|
24
|
+
|
25
|
+
it 'properly converts the date' do
|
26
|
+
strategy.starting_date(chrono).should eql Time.utc(2012, 7, 26, 3, 15, 12).to_date
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'when working with nothing' do
|
31
|
+
let(:fields) { { start_time: nil } }
|
32
|
+
|
33
|
+
it 'is nil' do
|
34
|
+
strategy.starting_date(chrono).should be_nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '#ending_date' do
|
40
|
+
context 'when working with a date/time' do
|
41
|
+
let(:fields) { { end_time: Time.utc(2012, 7, 26, 7, 12, 0) } }
|
42
|
+
|
43
|
+
it 'converts it to a date only' do
|
44
|
+
strategy.ending_date(chrono).should eql Time.utc(2012, 7, 26, 7, 12, 0).to_date
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'when working with a string' do
|
49
|
+
let(:fields) { { end_time: '2012-07-26 03:15:12' } }
|
50
|
+
|
51
|
+
it 'properly converts the date' do
|
52
|
+
strategy.ending_date(chrono).should eql Time.utc(2012, 7, 26, 3, 15, 12).to_date
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'when working with nothing' do
|
57
|
+
let(:fields) { { end_time: nil } }
|
58
|
+
|
59
|
+
it 'is nil' do
|
60
|
+
strategy.ending_date(chrono).should be_nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe '#inactive?' do
|
66
|
+
it 'is the opposite of in_progress?' do
|
67
|
+
chrono.should_receive(:in_progress?).and_return false
|
68
|
+
|
69
|
+
strategy.inactive?(chrono).should be_true
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe '#duration' do
|
74
|
+
context 'when the strategy represents something with a duration' do
|
75
|
+
before { strategy.should_receive(:duration_in_seconds).and_return(6263) }
|
76
|
+
|
77
|
+
it 'is a hash with the correct hours' do
|
78
|
+
strategy.duration(chrono)[:hours].should eql 1
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'is a hash with the correct minutes' do
|
82
|
+
strategy.duration(chrono)[:minutes].should eql 44
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'is a hash with the correct seconds' do
|
86
|
+
strategy.duration(chrono)[:seconds].should eql 23
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'when the strategy represents something with an even second time duration' do
|
91
|
+
before { strategy.should_receive(:duration_in_seconds).and_return(6240) }
|
92
|
+
|
93
|
+
it 'is a hash with the correct hours' do
|
94
|
+
strategy.duration(chrono)[:hours].should eql 1
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'is a hash with the correct minutes' do
|
98
|
+
strategy.duration(chrono)[:minutes].should eql 44
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'is a hash with the correct seconds' do
|
102
|
+
strategy.duration(chrono)[:seconds].should eql 0
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context 'when the strategy represents something with an even minute time duration' do
|
107
|
+
before { strategy.should_receive(:duration_in_seconds).and_return(3600) }
|
108
|
+
|
109
|
+
it 'is a hash with the correct hours' do
|
110
|
+
strategy.duration(chrono)[:hours].should eql 1
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'is a hash with the correct minutes' do
|
114
|
+
strategy.duration(chrono)[:minutes].should eql 0
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'is a hash with the correct seconds' do
|
118
|
+
strategy.duration(chrono)[:seconds].should eql 0
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context 'when the strategy represents something with a zero duration' do
|
123
|
+
before { strategy.should_receive(:duration_in_seconds).and_return(0) }
|
124
|
+
|
125
|
+
it 'is a hash with the correct hours' do
|
126
|
+
strategy.duration(chrono)[:hours].should eql 0
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'is a hash with the correct minutes' do
|
130
|
+
strategy.duration(chrono)[:minutes].should eql 0
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'is a hash with the correct seconds' do
|
134
|
+
strategy.duration(chrono)[:seconds].should eql 0
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context 'when duration in seconds returns an empty value' do
|
139
|
+
before { strategy.should_receive(:duration_in_seconds).and_return(nil) }
|
140
|
+
|
141
|
+
it 'is an empty hash' do
|
142
|
+
strategy.duration(chrono).should eql Hash.new
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe '#in_progress?', :timecop => true do
|
148
|
+
let(:later) { Time.local(2012, 7, 26, 6, 0, 26) }
|
149
|
+
let(:now) { Time.local(2012, 7, 26, 6, 0, 25) }
|
150
|
+
let(:past) { Time.local(2012, 7, 26, 6, 0, 24) }
|
151
|
+
|
152
|
+
before { Timecop.freeze(now) }
|
153
|
+
|
154
|
+
context 'when it does not have an absolute timeframe' do
|
155
|
+
before { strategy.should_receive(:has_absolute_timeframe?).and_return(false) }
|
156
|
+
|
157
|
+
it 'is false' do
|
158
|
+
strategy.in_progress?(chrono).should_not be_true
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
context 'when it does have an absolute timeframe' do
|
163
|
+
before { strategy.should_receive(:has_absolute_timeframe?).and_return(true) }
|
164
|
+
|
165
|
+
context 'and it has already started' do
|
166
|
+
context 'and already ended' do
|
167
|
+
let(:fields) do
|
168
|
+
{ start_time: past,
|
169
|
+
end_time: past }
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'is false' do
|
173
|
+
strategy.in_progress?(chrono).should_not be_true
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
context 'and ends now' do
|
178
|
+
let(:fields) do
|
179
|
+
{ start_time: past,
|
180
|
+
end_time: now }
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'is false' do
|
184
|
+
strategy.in_progress?(chrono).should_not be_true
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
context 'and ends later' do
|
189
|
+
let(:fields) do
|
190
|
+
{ start_time: past,
|
191
|
+
end_time: later }
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'is true' do
|
195
|
+
strategy.in_progress?(chrono).should be_true
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
context 'and there is a strategy that starts now' do
|
201
|
+
context 'and ends now' do
|
202
|
+
let(:fields) do
|
203
|
+
{ start_time: now,
|
204
|
+
end_time: now }
|
205
|
+
end
|
206
|
+
|
207
|
+
it 'is false' do
|
208
|
+
strategy.in_progress?(chrono).should_not be_true
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
context 'and ends later' do
|
213
|
+
let(:fields) do
|
214
|
+
{ start_time: now,
|
215
|
+
end_time: later }
|
216
|
+
end
|
217
|
+
|
218
|
+
it 'is true' do
|
219
|
+
strategy.in_progress?(chrono).should be_true
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
context 'and there is a strategy that has not yet started' do
|
225
|
+
let(:fields) do
|
226
|
+
{ start_time: later,
|
227
|
+
end_time: later }
|
228
|
+
end
|
229
|
+
|
230
|
+
it 'is false' do
|
231
|
+
strategy.in_progress?(chrono).should_not be_true
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
describe '#scheduled?' do
|
238
|
+
context 'when the time zone option is passed in' do
|
239
|
+
let(:field_names) { { time_zone: :time_zone } }
|
240
|
+
|
241
|
+
context 'and a time zone exists' do
|
242
|
+
let(:fields) { { time_zone: 'Alaska' } }
|
243
|
+
|
244
|
+
it 'is the time zone' do
|
245
|
+
strategy.scheduled?(chrono).should eql 'Alaska'
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
context 'and a time zone does not exist' do
|
250
|
+
let(:fields) { { time_zone: nil } }
|
251
|
+
|
252
|
+
it 'is the time zone' do
|
253
|
+
strategy.scheduled?(chrono).should be_nil
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
context 'when the time zone option is not passed in' do
|
259
|
+
let(:field_names) { Hash.new }
|
260
|
+
|
261
|
+
it 'is always true' do
|
262
|
+
strategy.scheduled?(chrono).should be_true
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
describe '#partially_scheduled?' do
|
268
|
+
context 'when the time zone option is passed in' do
|
269
|
+
let(:field_names) { { time_zone: :time_zone } }
|
270
|
+
|
271
|
+
context 'and a time zone exists' do
|
272
|
+
let(:fields) { { time_zone: 'Alaska' } }
|
273
|
+
|
274
|
+
it 'is the time zone' do
|
275
|
+
strategy.partially_scheduled?(chrono).should eql 'Alaska'
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
context 'and a time zone does not exist' do
|
280
|
+
let(:fields) { { time_zone: nil } }
|
281
|
+
|
282
|
+
it 'is the time zone' do
|
283
|
+
strategy.partially_scheduled?(chrono).should be_nil
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
context 'when the time zone option is not passed in' do
|
289
|
+
let(:field_names) { Hash.new }
|
290
|
+
|
291
|
+
it 'is always false' do
|
292
|
+
strategy.partially_scheduled?(chrono).should be_false
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
@@ -1,14 +1,15 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
class RelativeChronologicable < ActiveRecord::Base
|
4
|
-
|
4
|
+
extend Chronological
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
timeframe type: :relative,
|
7
|
+
starting_offset: :starting_offset,
|
8
|
+
ending_offset: :ending_offset,
|
9
|
+
base_of_offset: :base_datetime_utc
|
9
10
|
end
|
10
11
|
|
11
|
-
describe Chronological::
|
12
|
+
describe Chronological::RelativeStrategy, :timecop => true do
|
12
13
|
let(:now) { nil }
|
13
14
|
let(:starting_offset) { nil }
|
14
15
|
let(:ending_offset) { nil }
|
@@ -23,10 +24,133 @@ describe Chronological::RelativeTimeframe do
|
|
23
24
|
|
24
25
|
before { Timecop.freeze(now) }
|
25
26
|
|
26
|
-
|
27
|
+
describe '.by_date' do
|
28
|
+
before { RelativeChronologicable.delete_all }
|
27
29
|
|
28
|
-
|
29
|
-
|
30
|
+
context 'when there are two chronologicables that start at the same time' do
|
31
|
+
context 'but end at different times' do
|
32
|
+
let!(:chronologicable_1) { RelativeChronologicable.create(:base_datetime_utc => Time.now, :starting_offset => 3, :ending_offset => 2) }
|
33
|
+
let!(:chronologicable_2) { RelativeChronologicable.create(:base_datetime_utc => Time.now, :starting_offset => 3, :ending_offset => 1) }
|
34
|
+
|
35
|
+
context 'when no option is passed' do
|
36
|
+
it 'properly sorts them in ascending order' do
|
37
|
+
RelativeChronologicable.by_date.first.should eql chronologicable_1
|
38
|
+
RelativeChronologicable.by_date.last.should eql chronologicable_2
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'when the :desc option is passed' do
|
43
|
+
it 'sorts them backwards by the start date' do
|
44
|
+
RelativeChronologicable.by_date(:desc).first.should eql chronologicable_2
|
45
|
+
RelativeChronologicable.by_date(:desc).last.should eql chronologicable_1
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'and end at the same time' do
|
51
|
+
let!(:chronologicable_1) { RelativeChronologicable.create(:base_datetime_utc => Time.now, :starting_offset => 3, :ending_offset => 2) }
|
52
|
+
let!(:chronologicable_2) { RelativeChronologicable.create(:base_datetime_utc => Time.now, :starting_offset => 3, :ending_offset => 2) }
|
53
|
+
|
54
|
+
describe '.by_date' do
|
55
|
+
context 'when in ascending order' do
|
56
|
+
it 'does not matter what order they are in as long as they are all there' do
|
57
|
+
RelativeChronologicable.by_date.should include chronologicable_1
|
58
|
+
RelativeChronologicable.by_date.should include chronologicable_2
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'when in descending order' do
|
63
|
+
it 'does not matter what order they are in as long as they are all there' do
|
64
|
+
RelativeChronologicable.by_date(:desc).should include chronologicable_1
|
65
|
+
RelativeChronologicable.by_date(:desc).should include chronologicable_2
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'when there are two chronologicables that start at different times' do
|
73
|
+
context 'and end at different times' do
|
74
|
+
let!(:chronologicable_1) { RelativeChronologicable.create(:base_datetime_utc => Time.now, :starting_offset => 3, :ending_offset => 2) }
|
75
|
+
let!(:chronologicable_2) { RelativeChronologicable.create(:base_datetime_utc => Time.now, :starting_offset => 2, :ending_offset => 1) }
|
76
|
+
|
77
|
+
context 'when in ascending order' do
|
78
|
+
it 'sorts them by the start date' do
|
79
|
+
RelativeChronologicable.by_date.first.should eql chronologicable_1
|
80
|
+
RelativeChronologicable.by_date.last.should eql chronologicable_2
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'when in descending order' do
|
85
|
+
it 'sorts them backwards by the start date' do
|
86
|
+
RelativeChronologicable.by_date(:desc).first.should eql chronologicable_2
|
87
|
+
RelativeChronologicable.by_date(:desc).last.should eql chronologicable_1
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'but end at the same time' do
|
93
|
+
let!(:chronologicable_1) { RelativeChronologicable.create(:base_datetime_utc => Time.now, :starting_offset => 3, :ending_offset => 1) }
|
94
|
+
let!(:chronologicable_2) { RelativeChronologicable.create(:base_datetime_utc => Time.now, :starting_offset => 2, :ending_offset => 1) }
|
95
|
+
|
96
|
+
context 'when in ascending order' do
|
97
|
+
it 'sorts them by the start date' do
|
98
|
+
RelativeChronologicable.by_date.first.should eql chronologicable_1
|
99
|
+
RelativeChronologicable.by_date.last.should eql chronologicable_2
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context 'when in descending order' do
|
104
|
+
it 'sorts them backwards by the start date' do
|
105
|
+
RelativeChronologicable.by_date(:desc).first.should eql chronologicable_2
|
106
|
+
RelativeChronologicable.by_date(:desc).last.should eql chronologicable_1
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe '.by_duration' do
|
114
|
+
before { RelativeChronologicable.delete_all }
|
115
|
+
|
116
|
+
context 'when there are two chronologicables that are different durations' do
|
117
|
+
let!(:chronologicable_1) { RelativeChronologicable.create(:base_datetime_utc => Time.now, :starting_offset => 3, :ending_offset => 2) }
|
118
|
+
let!(:chronologicable_2) { RelativeChronologicable.create(:base_datetime_utc => Time.now, :starting_offset => 3, :ending_offset => 1) }
|
119
|
+
|
120
|
+
context 'when no option is passed' do
|
121
|
+
it 'properly sorts them in ascending order' do
|
122
|
+
RelativeChronologicable.by_date.first.should eql chronologicable_1
|
123
|
+
RelativeChronologicable.by_date.last.should eql chronologicable_2
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
context 'when the :desc option is passed' do
|
128
|
+
it 'sorts them backwards by the start date' do
|
129
|
+
RelativeChronologicable.by_date(:desc).first.should eql chronologicable_2
|
130
|
+
RelativeChronologicable.by_date(:desc).last.should eql chronologicable_1
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context 'when there are two chronologicables that are the same duration' do
|
136
|
+
let!(:chronologicable_1) { RelativeChronologicable.create(:base_datetime_utc => Time.now, :starting_offset => 3, :ending_offset => 1) }
|
137
|
+
let!(:chronologicable_2) { RelativeChronologicable.create(:base_datetime_utc => Time.now, :starting_offset => 3, :ending_offset => 1) }
|
138
|
+
|
139
|
+
context 'when no option is passed' do
|
140
|
+
it 'does not matter what order they are in' do
|
141
|
+
RelativeChronologicable.by_date.should include chronologicable_1
|
142
|
+
RelativeChronologicable.by_date.should include chronologicable_2
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
context 'when the :desc option is passed' do
|
147
|
+
it 'does not matter what order they are in' do
|
148
|
+
RelativeChronologicable.by_date(:desc).should include chronologicable_1
|
149
|
+
RelativeChronologicable.by_date(:desc).should include chronologicable_2
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
30
154
|
|
31
155
|
context 'when the base time is not set' do
|
32
156
|
let(:base_time) { nil }
|
@@ -75,7 +199,7 @@ describe Chronological::RelativeTimeframe do
|
|
75
199
|
end
|
76
200
|
|
77
201
|
it 'does not have a start time' do
|
78
|
-
chronologicable.
|
202
|
+
chronologicable.started_at.should be_nil
|
79
203
|
end
|
80
204
|
end
|
81
205
|
|
@@ -103,7 +227,7 @@ describe Chronological::RelativeTimeframe do
|
|
103
227
|
end
|
104
228
|
|
105
229
|
it 'does not have a start time' do
|
106
|
-
chronologicable.
|
230
|
+
chronologicable.started_at.should be_nil
|
107
231
|
end
|
108
232
|
end
|
109
233
|
|
@@ -111,7 +235,7 @@ describe Chronological::RelativeTimeframe do
|
|
111
235
|
let(:ending_offset) { 0 }
|
112
236
|
|
113
237
|
it 'does not have a end time' do
|
114
|
-
chronologicable.
|
238
|
+
chronologicable.ended_at.should be_nil
|
115
239
|
end
|
116
240
|
end
|
117
241
|
|
@@ -119,7 +243,7 @@ describe Chronological::RelativeTimeframe do
|
|
119
243
|
let(:ending_offset) { nil }
|
120
244
|
|
121
245
|
it 'does not have a end time' do
|
122
|
-
chronologicable.
|
246
|
+
chronologicable.ended_at.should be_nil
|
123
247
|
end
|
124
248
|
end
|
125
249
|
|
@@ -193,7 +317,7 @@ describe Chronological::RelativeTimeframe do
|
|
193
317
|
end
|
194
318
|
|
195
319
|
it 'does not have a start time' do
|
196
|
-
chronologicable.
|
320
|
+
chronologicable.started_at.should be_nil
|
197
321
|
end
|
198
322
|
end
|
199
323
|
|
@@ -241,7 +365,7 @@ describe Chronological::RelativeTimeframe do
|
|
241
365
|
end
|
242
366
|
|
243
367
|
it 'calculates the correct start time' do
|
244
|
-
chronologicable.
|
368
|
+
chronologicable.started_at.should eql Time.local(2012, 7, 26, 6, 0, 0)
|
245
369
|
end
|
246
370
|
end
|
247
371
|
|
@@ -249,7 +373,7 @@ describe Chronological::RelativeTimeframe do
|
|
249
373
|
let(:ending_offset) { 30 }
|
250
374
|
|
251
375
|
it 'calculates the correct end time' do
|
252
|
-
chronologicable.
|
376
|
+
chronologicable.ended_at.should eql Time.local(2012, 7, 26, 6, 0, 0)
|
253
377
|
end
|
254
378
|
end
|
255
379
|
|
@@ -257,7 +381,7 @@ describe Chronological::RelativeTimeframe do
|
|
257
381
|
let(:ending_offset) { nil }
|
258
382
|
|
259
383
|
it 'does not have a end time' do
|
260
|
-
chronologicable.
|
384
|
+
chronologicable.ended_at.should be_nil
|
261
385
|
end
|
262
386
|
end
|
263
387
|
end
|
@@ -270,6 +394,18 @@ describe Chronological::RelativeTimeframe do
|
|
270
394
|
context 'and before the ending offset' do
|
271
395
|
let(:ending_offset) { 30 }
|
272
396
|
|
397
|
+
it 'is not included in the started list' do
|
398
|
+
RelativeChronologicable.started.should_not include chronologicable
|
399
|
+
end
|
400
|
+
|
401
|
+
it 'is not included in the ended list' do
|
402
|
+
RelativeChronologicable.ended.should_not include chronologicable
|
403
|
+
end
|
404
|
+
|
405
|
+
it 'is included in the not yet ended list' do
|
406
|
+
RelativeChronologicable.not_yet_ended.should include chronologicable
|
407
|
+
end
|
408
|
+
|
273
409
|
it 'is not included in the in progress list' do
|
274
410
|
RelativeChronologicable.in_progress.should_not include chronologicable
|
275
411
|
end
|
@@ -288,6 +424,18 @@ describe Chronological::RelativeTimeframe do
|
|
288
424
|
context 'and before the ending offset' do
|
289
425
|
let(:ending_offset) { 29 }
|
290
426
|
|
427
|
+
it 'is included in the started list' do
|
428
|
+
RelativeChronologicable.started.should include chronologicable
|
429
|
+
end
|
430
|
+
|
431
|
+
it 'is not included in the ended list' do
|
432
|
+
RelativeChronologicable.ended.should_not include chronologicable
|
433
|
+
end
|
434
|
+
|
435
|
+
it 'is included in the not yet ended list' do
|
436
|
+
RelativeChronologicable.not_yet_ended.should include chronologicable
|
437
|
+
end
|
438
|
+
|
291
439
|
it 'is included in the in progress list' do
|
292
440
|
RelativeChronologicable.in_progress.should include chronologicable
|
293
441
|
end
|
@@ -300,6 +448,18 @@ describe Chronological::RelativeTimeframe do
|
|
300
448
|
context 'and the same as the ending offset' do
|
301
449
|
let(:ending_offset) { 30 }
|
302
450
|
|
451
|
+
it 'is included in the started list' do
|
452
|
+
RelativeChronologicable.started.should include chronologicable
|
453
|
+
end
|
454
|
+
|
455
|
+
it 'is included in the ended list' do
|
456
|
+
RelativeChronologicable.ended.should include chronologicable
|
457
|
+
end
|
458
|
+
|
459
|
+
it 'is not included in the not yet ended list' do
|
460
|
+
RelativeChronologicable.not_yet_ended.should_not include chronologicable
|
461
|
+
end
|
462
|
+
|
303
463
|
it 'is not included in the in progress list' do
|
304
464
|
RelativeChronologicable.in_progress.should_not include chronologicable
|
305
465
|
end
|
@@ -318,6 +478,18 @@ describe Chronological::RelativeTimeframe do
|
|
318
478
|
context 'and before the ending offset' do
|
319
479
|
let(:ending_offset) { 27 }
|
320
480
|
|
481
|
+
it 'is included in the started list' do
|
482
|
+
RelativeChronologicable.started.should include chronologicable
|
483
|
+
end
|
484
|
+
|
485
|
+
it 'is not included in the ended list' do
|
486
|
+
RelativeChronologicable.ended.should_not include chronologicable
|
487
|
+
end
|
488
|
+
|
489
|
+
it 'is included in the not yet ended list' do
|
490
|
+
RelativeChronologicable.not_yet_ended.should include chronologicable
|
491
|
+
end
|
492
|
+
|
321
493
|
it 'is included in the in progress list' do
|
322
494
|
RelativeChronologicable.in_progress.should include chronologicable
|
323
495
|
end
|
@@ -330,6 +502,18 @@ describe Chronological::RelativeTimeframe do
|
|
330
502
|
context 'and the same as the ending offset' do
|
331
503
|
let(:ending_offset) { 28 }
|
332
504
|
|
505
|
+
it 'is included in the started list' do
|
506
|
+
RelativeChronologicable.started.should include chronologicable
|
507
|
+
end
|
508
|
+
|
509
|
+
it 'is included in the ended list' do
|
510
|
+
RelativeChronologicable.ended.should include chronologicable
|
511
|
+
end
|
512
|
+
|
513
|
+
it 'is not included in the not yet ended list' do
|
514
|
+
RelativeChronologicable.not_yet_ended.should_not include chronologicable
|
515
|
+
end
|
516
|
+
|
333
517
|
it 'is not included in the in progress list' do
|
334
518
|
RelativeChronologicable.in_progress.should_not include chronologicable
|
335
519
|
end
|
@@ -342,6 +526,18 @@ describe Chronological::RelativeTimeframe do
|
|
342
526
|
context 'and after the ending offset' do
|
343
527
|
let(:ending_offset) { 29 }
|
344
528
|
|
529
|
+
it 'is included in the started list' do
|
530
|
+
RelativeChronologicable.started.should include chronologicable
|
531
|
+
end
|
532
|
+
|
533
|
+
it 'is included in the ended list' do
|
534
|
+
RelativeChronologicable.ended.should include chronologicable
|
535
|
+
end
|
536
|
+
|
537
|
+
it 'is not included in the not yet ended list' do
|
538
|
+
RelativeChronologicable.not_yet_ended.should_not include chronologicable
|
539
|
+
end
|
540
|
+
|
345
541
|
it 'is not included in the in progress list' do
|
346
542
|
RelativeChronologicable.in_progress.should_not include chronologicable
|
347
543
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Chronological::StrategyResolver do
|
4
|
+
describe '.resolve' do
|
5
|
+
let(:resolved_strategy) { Chronological::StrategyResolver.resolve(options_to_resolve) }
|
6
|
+
|
7
|
+
context 'when passed a strategy name' do
|
8
|
+
let(:options_to_resolve) { { :type => :absolute } }
|
9
|
+
|
10
|
+
it 'resolves to the proper class' do
|
11
|
+
resolved_strategy.should be_a Chronological::AbsoluteStrategy
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'tells the strategy to create itself with the default fields' do
|
15
|
+
Chronological::AbsoluteStrategy.should_receive(:new).with starting_time: :started_at,
|
16
|
+
ending_time: :ended_at,
|
17
|
+
starting_date: :started_on,
|
18
|
+
ending_date: :ended_on
|
19
|
+
|
20
|
+
resolved_strategy
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'with some overridden field name options' do
|
24
|
+
let(:options_to_resolve) { { type: :absolute,
|
25
|
+
starting_time: :my_starting_field } }
|
26
|
+
|
27
|
+
it 'overrides the proper default fields and tells the strategy to create itself with those' do
|
28
|
+
Chronological::AbsoluteStrategy.should_receive(:new).with starting_time: :my_starting_field,
|
29
|
+
ending_time: :ended_at,
|
30
|
+
starting_date: :started_on,
|
31
|
+
ending_date: :ended_on
|
32
|
+
|
33
|
+
resolved_strategy
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'when passed exact field names that relate to a strategy' do
|
39
|
+
let(:options_to_resolve) { { starting_time: :my_starting_field,
|
40
|
+
ending_time: :my_ending_field } }
|
41
|
+
|
42
|
+
it 'resolves the proper strategy to instantiate' do
|
43
|
+
resolved_strategy.should be_a Chronological::AbsoluteStrategy
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'when passed something it does not know how to resolve' do
|
48
|
+
let(:options_to_resolve) { { start_me_up: :my_starting_field,
|
49
|
+
its_the_end_of_the_world_as_we_know_it: :my_ending_field } }
|
50
|
+
|
51
|
+
it 'resolves the proper strategy to instantiate' do
|
52
|
+
lambda { Chronological::StrategyResolver.resolve(options_to_resolve) }.should raise_error Chronological::UndefinedStrategy
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|