fat_core 2.0.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,677 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Period do
4
- before :each do
5
- # Pretend it is this date. Not at beg or end of year, quarter,
6
- # month, or week. It is a Wednesday
7
- allow(Date).to receive_messages(today: Date.parse('2012-07-18'))
8
- allow(Date).to receive_messages(current: Date.parse('2012-07-18'))
9
- end
10
-
11
- describe 'initialization' do
12
- it 'should be initializable with date strings' do
13
- expect(Period.new('2013-01-01', '2013-12-13')).to be_instance_of Period
14
- end
15
-
16
- it 'should be initializable with Dates' do
17
- expect(Period.new('2013-01-01', '2013-12-13'))
18
- .to be_instance_of Period
19
- end
20
-
21
- it 'should raise a ArgumentError if last > first' do
22
- expect {
23
- Period.new('2013-01-01', '2012-12-31')
24
- }.to raise_error ArgumentError
25
- end
26
-
27
- it 'should raise a ArgumentError if initialized with invalid date string' do
28
- expect {
29
- Period.new('2013-01-01', '2013-12-32')
30
- }.to raise_error ArgumentError
31
- expect {
32
- Period.new('2013-13-01', '2013-12-31')
33
- }.to raise_error ArgumentError
34
- end
35
-
36
- it 'should raise a ArgumentError if initialized otherwise' do
37
- expect {
38
- Period.new(2013 - 1 - 1, 2013 - 12 - 31)
39
- }.to raise_error ArgumentError
40
- end
41
- end
42
-
43
- describe 'class methods' do
44
- it 'should be able to parse a period phrase' do
45
- pd = Period.parse_phrase('from this_year')
46
- expect(pd.first).to eq(Date.parse('2012-01-01'))
47
- expect(pd.last).to eq(Date.parse('2012-12-31'))
48
-
49
- pd = Period.parse_phrase('from 2012-07 to 2012')
50
- expect(pd.first).to eq(Date.parse('2012-07-01'))
51
- expect(pd.last).to eq(Date.parse('2012-12-31'))
52
-
53
- pd = Period.parse_phrase('from 1H')
54
- expect(pd.first).to eq(Date.parse('2012-01-01'))
55
- expect(pd.last).to eq(Date.parse('2012-06-30'))
56
-
57
- pd = Period.parse_phrase('to 2H')
58
- expect(pd.first).to eq(Date.parse('2012-07-01'))
59
- expect(pd.last).to eq(Date.parse('2012-12-31'))
60
-
61
- pd = Period.parse_phrase('from 2Q')
62
- expect(pd.first).to eq(Date.parse('2012-04-01'))
63
- expect(pd.last).to eq(Date.parse('2012-06-30'))
64
-
65
- pd = Period.parse_phrase('to 3Q')
66
- expect(pd.first).to eq(Date.parse('2012-07-01'))
67
- expect(pd.last).to eq(Date.parse('2012-09-30'))
68
-
69
- pd = Period.parse_phrase('to 2012-2Q')
70
- expect(pd.first).to eq(Date.parse('2012-04-01'))
71
- expect(pd.last).to eq(Date.parse('2012-06-30'))
72
-
73
- pd = Period.parse_phrase('from 2012-1Q')
74
- expect(pd.first).to eq(Date.parse('2012-01-01'))
75
- expect(pd.last).to eq(Date.parse('2012-03-31'))
76
-
77
- pd = Period.parse_phrase('from 2H')
78
- expect(pd.first).to eq(Date.parse('2012-07-01'))
79
- expect(pd.last).to eq(Date.parse('2012-12-31'))
80
-
81
- pd = Period.parse_phrase('to 1H')
82
- expect(pd.first).to eq(Date.parse('2012-01-01'))
83
- expect(pd.last).to eq(Date.parse('2012-06-30'))
84
-
85
- pd = Period.parse_phrase('to 2012-2H')
86
- expect(pd.first).to eq(Date.parse('2012-07-01'))
87
- expect(pd.last).to eq(Date.parse('2012-12-31'))
88
-
89
- pd = Period.parse_phrase('from 2012-1H')
90
- expect(pd.first).to eq(Date.parse('2012-01-01'))
91
- expect(pd.last).to eq(Date.parse('2012-06-30'))
92
-
93
- pd = Period.parse_phrase('to 2012')
94
- expect(pd.first).to eq(Date.parse('2012-01-01'))
95
- expect(pd.last).to eq(Date.parse('2012-12-31'))
96
-
97
- pd = Period.parse_phrase('from 2012')
98
- expect(pd.first).to eq(Date.parse('2012-01-01'))
99
- expect(pd.last).to eq(Date.parse('2012-12-31'))
100
-
101
- pd = Period.parse_phrase('2012')
102
- expect(pd.first).to eq(Date.parse('2012-01-01'))
103
- expect(pd.last).to eq(Date.parse('2012-12-31'))
104
-
105
- pd = Period.parse_phrase('this_year')
106
- expect(pd.first).to eq(Date.parse('2012-01-01'))
107
- expect(pd.last).to eq(Date.parse('2012-12-31'))
108
-
109
- pd = Period.parse_phrase('from last_year to this_year')
110
- expect(pd.first).to eq(Date.parse('2011-01-01'))
111
- expect(pd.last).to eq(Date.parse('2012-12-31'))
112
-
113
- pd = Period.parse_phrase('from last_year to this_year')
114
- expect(pd.first).to eq(Date.parse('2011-01-01'))
115
- expect(pd.last).to eq(Date.parse('2012-12-31'))
116
- end
117
-
118
- it 'should return nil when parsing never' do
119
- expect(Period.parse('never')).to be_nil
120
- end
121
-
122
- it 'should know how to parse a pair of date specs' do
123
- expect(Period.parse('2014-3Q').first).to eq Date.parse('2014-07-01')
124
- expect(Period.parse('2014-3Q').last).to eq Date.parse('2014-09-30')
125
- expect(Period.parse('2014-3Q').last).to eq Date.parse('2014-09-30')
126
- end
127
-
128
- it 'should know what the valid chunk syms are' do
129
- expect(Period.chunk_syms.size).to eq(10)
130
- end
131
-
132
- it 'should know the days in a chunk sym' do
133
- expect(Period.chunk_sym_to_days(:year)).to eq(365)
134
- expect(Period.chunk_sym_to_days(:quarter)).to eq(90)
135
- expect(Period.chunk_sym_to_days(:bimonth)).to eq(60)
136
- expect(Period.chunk_sym_to_days(:month)).to eq(30)
137
- expect(Period.chunk_sym_to_days(:semimonth)).to eq(15)
138
- expect(Period.chunk_sym_to_days(:biweek)).to eq(14)
139
- expect(Period.chunk_sym_to_days(:week)).to eq(7)
140
- expect(Period.chunk_sym_to_days(:day)).to eq(1)
141
- expect(Period.chunk_sym_to_days(:irregular)).to eq(30)
142
- expect {
143
- Period.chunk_sym_to_days(:eon)
144
- }.to raise_error ArgumentError
145
- end
146
-
147
- it 'should know the maximum days in a chunk sym' do
148
- expect(Period.chunk_sym_to_max_days(:year)).to eq(366)
149
- expect(Period.chunk_sym_to_max_days(:quarter)).to eq(92)
150
- expect(Period.chunk_sym_to_max_days(:bimonth)).to eq(62)
151
- expect(Period.chunk_sym_to_max_days(:month)).to eq(31)
152
- expect(Period.chunk_sym_to_max_days(:semimonth)).to eq(16)
153
- expect(Period.chunk_sym_to_max_days(:biweek)).to eq(14)
154
- expect(Period.chunk_sym_to_max_days(:week)).to eq(7)
155
- expect(Period.chunk_sym_to_max_days(:day)).to eq(1)
156
- expect { Period.chunk_sym_to_max_days(:irregular) }
157
- .to raise_error ArgumentError
158
- expect {
159
- Period.chunk_sym_to_days(:eon)
160
- }.to raise_error ArgumentError
161
- end
162
-
163
- it 'should know the chunk sym for given days but only :year, :quarter, :month' do
164
- (356..376).each { |d| expect(Period.days_to_chunk_sym(d)).to eq(:year) }
165
- (180..183).each { |d| expect(Period.days_to_chunk_sym(d)).to eq(:half) }
166
- (86..96).each { |d| expect(Period.days_to_chunk_sym(d)).to eq(:quarter) }
167
- (28..31).each { |d| expect(Period.days_to_chunk_sym(d)).to eq(:month) }
168
- expect(Period.days_to_chunk_sym(7)).to eq(:week)
169
- expect(Period.days_to_chunk_sym(1)).to eq(:day)
170
- end
171
-
172
- it 'should know what to call a chunk based on its size' do
173
- expect(Period.new('2011-01-01', '2011-12-31').chunk_name).to eq('Year')
174
- expect(Period.new('2011-01-01', '2011-06-30').chunk_name).to eq('Half')
175
- expect(Period.new('2011-01-01', '2011-03-31').chunk_name).to eq('Quarter')
176
- expect(Period.new('2011-01-01', '2011-02-28').chunk_name)
177
- .to eq('Bi-month')
178
- expect(Period.new('2011-01-01', '2011-01-31').chunk_name).to eq('Month')
179
- expect(Period.new('2011-01-01', '2011-01-15').chunk_name)
180
- .to eq('Semi-month')
181
- expect(Period.new('2011-01-09', '2011-01-22').chunk_name).to eq('Bi-week')
182
- expect(Period.new('2011-01-01', '2011-01-07').chunk_name).to eq('Week')
183
- expect(Period.new('2011-01-01', '2011-01-01').chunk_name).to eq('Day')
184
- expect(Period.new('2011-01-01', '2011-01-21').chunk_name).to eq('Period')
185
- # Only size matters, not whether the period begins and ends on
186
- # calendar unit boundaries.
187
- expect(Period.new('2011-02-11', '2011-03-10').chunk_name).to eq('Month')
188
- end
189
- end
190
-
191
- describe 'sorting' do
192
- it 'should sort by first, then size' do
193
- periods = []
194
- periods << Period.new('2012-07-01', '2012-07-31')
195
- periods << Period.new('2012-06-01', '2012-06-30')
196
- periods << Period.new('2012-08-01', '2012-08-31')
197
- periods.sort!
198
- # First by start_date, then shortest period to longest
199
- expect(periods[0].first).to eq(Date.parse('2012-06-01'))
200
- expect(periods[1].first).to eq(Date.parse('2012-07-01'))
201
- expect(periods[2].first).to eq(Date.parse('2012-08-01'))
202
- expect(periods[0].last).to eq(Date.parse('2012-06-30'))
203
- expect(periods[1].last).to eq(Date.parse('2012-07-31'))
204
- expect(periods[2].last).to eq(Date.parse('2012-08-31'))
205
- end
206
-
207
- it 'should return nil if comparing incomparables' do
208
- pd = Period.new('2012-08-01', '2012-08-31')
209
- rg = (Date.parse('2012-08-01')..Date.parse('2012-08-31'))
210
- expect(pd <=> rg).to be_nil
211
- end
212
- end
213
-
214
- describe 'instance methods' do
215
- it 'should be able to set first' do
216
- pp = Period.new('2014-12-07', '2014-12-17')
217
- pp.first = Date.parse('2014-12-01')
218
- expect(pp.first).to eq Date.parse('2014-12-01')
219
- end
220
-
221
- it 'should be able to set last' do
222
- pp = Period.new('2014-12-07', '2014-12-17')
223
- pp.last = Date.parse('2014-12-31')
224
- expect(pp.last).to eq Date.parse('2014-12-31')
225
- end
226
-
227
- it 'should not be able to set first > last' do
228
- pp = Period.new('2014-12-07', '2014-12-17')
229
- expect {
230
- pp.first = Date.parse('2014-12-31')
231
- }.to raise_error ArgumentError
232
- end
233
-
234
- it 'should not be able to set last < first' do
235
- pp = Period.new('2014-12-07', '2014-12-17')
236
- expect {
237
- pp.last = Date.parse('2014-12-01')
238
- }.to raise_error ArgumentError
239
- end
240
-
241
- it 'should be able to compare for equality' do
242
- pp1 = Period.new('2013-01-01', '2013-12-31')
243
- pp2 = Period.new('2013-01-01', '2013-12-31')
244
- pp3 = Period.new('2013-01-01', '2013-12-30')
245
- expect((pp1 == pp2)).to be true
246
- expect((pp1 == pp3)).to_not be true
247
- expect((pp1 != pp3)).to be true
248
- end
249
-
250
- it 'should be able to convert into a Range' do
251
- pp = Period.new('2013-01-01', '2013-12-31')
252
- rr = Period.new('2013-01-01', '2013-12-31').to_range
253
- expect(rr).to be_instance_of Range
254
- expect(rr.first).to eq(pp.first)
255
- expect(rr.last).to eq(pp.last)
256
- end
257
-
258
- it 'should be able to tell if it contains a date' do
259
- pp = Period.new('2013-01-01', '2013-12-31')
260
- expect(pp.contains?(Date.parse('2013-01-01'))).to be true
261
- expect(pp.contains?(Date.parse('2013-07-04'))).to be true
262
- expect(pp.contains?(Date.parse('2013-12-31'))).to be true
263
- expect(pp.contains?(Date.parse('2012-07-04'))).to be false
264
- end
265
-
266
- it 'should raise an error if contains? arg is not a date' do
267
- pp = Period.new('2013-01-01', '2013-12-31')
268
- expect {
269
- pp.contains?(Period.new('2013-06-01', '2013-06-30'))
270
- }.to raise_error(/must be a Date/)
271
-
272
- # But not if argument can be converted to date with to_date
273
- expect {
274
- pp.contains?(Time.now)
275
- }.not_to raise_error
276
- end
277
-
278
- it 'should be able to tell if it contains a date with ===' do
279
- pp = Period.new('2013-01-01', '2013-12-31')
280
- expect(pp === Date.parse('2013-01-01')).to be true
281
- expect(pp === Date.parse('2013-07-04')).to be true
282
- expect(pp === Date.parse('2013-12-31')).to be true
283
- expect(pp === Date.parse('2012-07-04')).to be false
284
- end
285
-
286
- it 'should be able to convert itself to days' do
287
- expect(Period.new('2013-01-01', '2013-01-01').days).to eq(1)
288
- expect(Period.new('2013-01-01', '2013-12-31').days).to eq(365)
289
- end
290
-
291
- it 'should be able to convert itself to fractional months' do
292
- expect(Period.new('2013-01-01', '2013-01-01').months).to eq(1 / 30.436875)
293
- expect(Period.new('2013-01-01', '2013-12-31').months(30)).to eq(365 / 30.0)
294
- expect(Period.new('2013-01-01', '2013-06-30').months.round(0)).to eq(6.0)
295
- end
296
-
297
- it 'should be able to convert itself to fractional years' do
298
- expect(Period.new('2013-01-01', '2013-01-01').years).to eq(1 / 365.2425)
299
- expect(Period.new('2013-01-01', '2013-12-31').years(365)).to eq(1.0)
300
- expect(Period.new('2013-01-01', '2013-06-30').years.round(1)).to eq(0.5)
301
- end
302
-
303
- it 'should be able to enumerate its days' do
304
- Period.parse('2014-12').each do |dy|
305
- expect(dy.class).to eq Date
306
- end
307
- end
308
-
309
- it 'should be able to return the trading days within period' do
310
- tds = Period.parse('2014-12').trading_days
311
- expect(tds.count).to eq(22)
312
- end
313
-
314
- it 'should know its size' do
315
- pp = Period.new('2013-01-01', '2013-12-31')
316
- expect(pp.size).to eq 365
317
- expect(pp.length).to eq 365
318
- end
319
-
320
- it 'should implement the each method' do
321
- pp = Period.new('2013-12-01', '2013-12-31')
322
- pp.map(&:iso)
323
- .each { |s| expect(s).to match(/\d{4}-\d\d-\d\d/) }
324
- end
325
-
326
- it 'should be able to make a concise period string' do
327
- expect(Period.new('2013-01-01', '2013-12-31').to_s).to eq('2013')
328
- expect(Period.new('2013-04-01', '2013-06-30').to_s).to eq('2013-2Q')
329
- expect(Period.new('2013-03-01', '2013-03-31').to_s).to eq('2013-03')
330
- expect(Period.new('2013-03-11', '2013-10-31').to_s)
331
- .to eq('2013-03-11 to 2013-10-31')
332
- end
333
-
334
- it 'should be able to make a TeX string' do
335
- expect(Period.new('2013-01-01', '2013-12-31').tex_quote)
336
- .to eq('2013-01-01--2013-12-31')
337
- end
338
-
339
- # Note in the following that first period must begin within self.
340
- it 'should be able to chunk into years' do
341
- chunks = Period.new('2009-12-15', '2013-01-10').chunks(size: :year)
342
- expect(chunks.size).to eq(3)
343
- expect(chunks[0].first.iso).to eq('2010-01-01')
344
- expect(chunks[0].last.iso).to eq('2010-12-31')
345
- expect(chunks[1].first.iso).to eq('2011-01-01')
346
- expect(chunks[1].last.iso).to eq('2011-12-31')
347
- expect(chunks[2].first.iso).to eq('2012-01-01')
348
- expect(chunks[2].last.iso).to eq('2012-12-31')
349
- end
350
-
351
- it 'should be able to chunk into halves' do
352
- chunks = Period.new('2009-12-15', '2013-01-10').chunks(size: :half)
353
- expect(chunks.size).to eq(6)
354
- expect(chunks[0].first.iso).to eq('2010-01-01')
355
- expect(chunks[0].last.iso).to eq('2010-06-30')
356
- expect(chunks[1].first.iso).to eq('2010-07-01')
357
- expect(chunks[1].last.iso).to eq('2010-12-31')
358
- expect(chunks[2].first.iso).to eq('2011-01-01')
359
- expect(chunks[2].last.iso).to eq('2011-06-30')
360
- expect(chunks.last.first.iso).to eq('2012-07-01')
361
- expect(chunks.last.last.iso).to eq('2012-12-31')
362
- end
363
-
364
- it 'should be able to chunk into quarters' do
365
- chunks = Period.new('2009-12-15', '2013-01-10').chunks(size: :quarter)
366
- expect(chunks.size).to eq(12)
367
- expect(chunks[0].first.iso).to eq('2010-01-01')
368
- expect(chunks[0].last.iso).to eq('2010-03-31')
369
- expect(chunks[1].first.iso).to eq('2010-04-01')
370
- expect(chunks[1].last.iso).to eq('2010-06-30')
371
- expect(chunks[2].first.iso).to eq('2010-07-01')
372
- expect(chunks[2].last.iso).to eq('2010-09-30')
373
- expect(chunks.last.first.iso).to eq('2012-10-01')
374
- expect(chunks.last.last.iso).to eq('2012-12-31')
375
- end
376
-
377
- it 'should be able to chunk into bimonths' do
378
- chunks = Period.new('2009-12-15', '2013-01-10').chunks(size: :bimonth)
379
- expect(chunks.size).to eq(18)
380
- expect(chunks[0].first.iso).to eq('2010-01-01')
381
- expect(chunks[0].last.iso).to eq('2010-02-28')
382
- expect(chunks[1].first.iso).to eq('2010-03-01')
383
- expect(chunks[1].last.iso).to eq('2010-04-30')
384
- expect(chunks[2].first.iso).to eq('2010-05-01')
385
- expect(chunks[2].last.iso).to eq('2010-06-30')
386
- expect(chunks.last.first.iso).to eq('2012-11-01')
387
- expect(chunks.last.last.iso).to eq('2012-12-31')
388
- end
389
-
390
- it 'should be able to chunk into months' do
391
- chunks = Period.new('2009-12-15', '2013-01-10').chunks(size: :month)
392
- expect(chunks.size).to eq(36)
393
- expect(chunks[0].first.iso).to eq('2010-01-01')
394
- expect(chunks[0].last.iso).to eq('2010-01-31')
395
- expect(chunks[1].first.iso).to eq('2010-02-01')
396
- expect(chunks[1].last.iso).to eq('2010-02-28')
397
- expect(chunks[2].first.iso).to eq('2010-03-01')
398
- expect(chunks[2].last.iso).to eq('2010-03-31')
399
- expect(chunks.last.first.iso).to eq('2012-12-01')
400
- expect(chunks.last.last.iso).to eq('2012-12-31')
401
- end
402
-
403
- it 'should be able to chunk into semimonths' do
404
- chunks = Period.new('2009-12-25', '2013-01-10').chunks(size: :semimonth)
405
- expect(chunks.size).to eq(72)
406
- expect(chunks[0].first.iso).to eq('2010-01-01')
407
- expect(chunks[0].last.iso).to eq('2010-01-15')
408
- expect(chunks[1].first.iso).to eq('2010-01-16')
409
- expect(chunks[1].last.iso).to eq('2010-01-31')
410
- expect(chunks[2].first.iso).to eq('2010-02-01')
411
- expect(chunks[2].last.iso).to eq('2010-02-15')
412
- expect(chunks.last.first.iso).to eq('2012-12-16')
413
- expect(chunks.last.last.iso).to eq('2012-12-31')
414
- end
415
-
416
- it 'should be able to chunk into biweeks' do
417
- chunks = Period.new('2009-12-29', '2013-01-10').chunks(size: :biweek)
418
- expect(chunks.size).to be >= (26 * 3)
419
- expect(chunks[0].first.iso).to eq('2010-01-04')
420
- expect(chunks[0].last.iso).to eq('2010-01-17')
421
- expect(chunks[1].first.iso).to eq('2010-01-18')
422
- expect(chunks[1].last.iso).to eq('2010-01-31')
423
- expect(chunks[2].first.iso).to eq('2010-02-01')
424
- expect(chunks[2].last.iso).to eq('2010-02-14')
425
- expect(chunks.last.first.iso).to eq('2012-12-17')
426
- expect(chunks.last.last.iso).to eq('2012-12-30')
427
- end
428
-
429
- it 'should be able to chunk into weeks' do
430
- chunks = Period.new('2010-01-01', '2012-12-31').chunks(size: :week)
431
- expect(chunks.size).to be >= (52 * 3)
432
- expect(chunks[0].first.iso).to eq('2010-01-04')
433
- expect(chunks[0].last.iso).to eq('2010-01-10')
434
- expect(chunks[1].first.iso).to eq('2010-01-11')
435
- expect(chunks[1].last.iso).to eq('2010-01-17')
436
- expect(chunks[2].first.iso).to eq('2010-01-18')
437
- expect(chunks[2].last.iso).to eq('2010-01-24')
438
- expect(chunks.last.first.iso).to eq('2012-12-24')
439
- expect(chunks.last.last.iso).to eq('2012-12-30')
440
- end
441
-
442
- it 'should be able to chunk into days' do
443
- chunks = Period.new('2012-12-28', '2012-12-31').chunks(size: :day)
444
- expect(chunks.size).to eq(4)
445
- expect(chunks[0].first.iso).to eq('2012-12-28')
446
- expect(chunks[0].last.iso).to eq('2012-12-28')
447
- expect(chunks[1].first.iso).to eq('2012-12-29')
448
- expect(chunks[1].last.iso).to eq('2012-12-29')
449
- expect(chunks[2].first.iso).to eq('2012-12-30')
450
- expect(chunks[2].last.iso).to eq('2012-12-30')
451
- expect(chunks.last.first.iso).to eq('2012-12-31')
452
- expect(chunks.last.last.iso).to eq('2012-12-31')
453
- end
454
-
455
- it 'should raise error for invalid chunk name' do
456
- expect {
457
- Period.new('2012-12-28', '2012-12-31').chunks(size: :wally)
458
- }.to raise_error /unknown chunk sym/
459
- end
460
-
461
- it 'should raise error for too large a chunk and no partials allowed' do
462
- expect {
463
- Period.new('2012-12-01', '2012-12-31').
464
- chunks(size: :bimonth, partial_first: false, partial_last: false)
465
- }.to raise_error /longer than/
466
- end
467
-
468
- it 'should return period itself for too large chunk if partials allowed' do
469
- pd = Period.new('2012-12-01', '2012-12-31')
470
- expect(pd.chunks(size: :bimonth, partial_first: true).first).to eq(pd)
471
- expect(pd.chunks(size: :bimonth, partial_last: true).first).to eq(pd)
472
- end
473
-
474
- it 'should not include a partial final chunk by default' do
475
- chunks = Period.new('2012-01-01', '2012-03-30').chunks(size: :month)
476
- expect(chunks.size).to eq(2)
477
- end
478
-
479
- it 'should include a partial final chunk if partial_last' do
480
- chunks = Period.new('2012-01-01', '2012-03-30')
481
- .chunks(size: :month, partial_last: true)
482
- expect(chunks.size).to eq(3)
483
- expect(chunks.last.first).to eq(Date.parse('2012-03-01'))
484
- expect(chunks.last.last).to eq(Date.parse('2012-03-30'))
485
- end
486
-
487
- it 'should include a final chunk beyond end_date if round_up' do
488
- chunks = Period.new('2012-01-01', '2012-03-30')
489
- .chunks(size: :month, round_up_last: true)
490
- expect(chunks.size).to eq(3)
491
- expect(chunks.last.first).to eq(Date.parse('2012-03-01'))
492
- expect(chunks.last.last).to eq(Date.parse('2012-03-31'))
493
- end
494
-
495
- it 'should not include a partial initial chunk by default' do
496
- chunks = Period.new('2012-01-13', '2012-03-31').chunks(size: :month)
497
- expect(chunks.size).to eq(2)
498
- expect(chunks[0].first).to eq(Date.parse('2012-02-01'))
499
- expect(chunks[0].last).to eq(Date.parse('2012-02-29'))
500
- end
501
-
502
- it 'should include a partial initial chunk by if partial_first' do
503
- chunks = Period.new('2012-01-13', '2012-03-31')
504
- .chunks(size: :month, partial_first: true)
505
- expect(chunks.size).to eq(3)
506
- expect(chunks[0].first).to eq(Date.parse('2012-01-13'))
507
- expect(chunks[0].last).to eq(Date.parse('2012-01-31'))
508
- end
509
-
510
- it 'should include a final chunk beyond end_date if round_up' do
511
- chunks = Period.new('2012-01-01', '2012-03-30')
512
- .chunks(size: :month, round_up_last: true)
513
- expect(chunks.size).to eq(3)
514
- expect(chunks.last.first).to eq(Date.parse('2012-03-01'))
515
- expect(chunks.last.last).to eq(Date.parse('2012-03-31'))
516
- end
517
-
518
- it 'should be able to determine its chunk_sym' do
519
- expect(Period.new('2013-01-01', '2013-12-31').chunk_sym).to eq(:year)
520
- expect(Period.new('2012-01-01', '2013-12-31').chunk_sym).to_not eq(:year)
521
-
522
- expect(Period.new('2013-01-01', '2013-06-30').chunk_sym).to eq(:half)
523
- expect(Period.new('2012-01-01', '2013-05-31').chunk_sym).to_not eq(:half)
524
-
525
- expect(Period.new('2013-04-01', '2013-06-30').chunk_sym).to eq(:quarter)
526
- expect(Period.new('2013-04-01', '2013-09-30').chunk_sym)
527
- .to_not eq(:quarter)
528
-
529
- expect(Period.new('2013-03-01', '2013-04-30').chunk_sym).to eq(:bimonth)
530
- expect(Period.new('2013-03-01', '2013-06-30').chunk_sym)
531
- .to_not eq(:bimonth)
532
-
533
- expect(Period.new('2013-04-01', '2013-04-30').chunk_sym).to eq(:month)
534
- expect(Period.new('2013-04-01', '2013-05-30').chunk_sym).to_not eq(:month)
535
-
536
- expect(Period.new('2013-05-16', '2013-05-31').chunk_sym).to eq(:semimonth)
537
- expect(Period.new('2013-05-16', '2013-06-30').chunk_sym)
538
- .to_not eq(:semimonth)
539
-
540
- expect(Period.new('2013-11-04', '2013-11-17').chunk_sym).to eq(:biweek)
541
- expect(Period.new('2013-11-04', '2013-11-24').chunk_sym)
542
- .to_not eq(:biweek)
543
-
544
- expect(Period.new('2013-11-11', '2013-11-17').chunk_sym).to eq(:week)
545
- expect(Period.new('2013-11-11', '2013-11-24').chunk_sym).to_not eq(:week)
546
-
547
- expect(Period.new('2013-11-10', '2013-11-10').chunk_sym).to eq(:day)
548
- expect(Period.new('2013-11-10', '2013-11-11').chunk_sym).to_not eq(:day)
549
-
550
- expect(Period.new('2013-11-02', '2013-12-16').chunk_sym).to eq(:irregular)
551
- end
552
-
553
- it 'should know if it\'s a subset of another period' do
554
- year = Period.parse('this_year')
555
- month = Period.parse('this_month')
556
- expect(month.subset_of?(year)).to be true
557
- expect(year.subset_of?(year)).to be true
558
- end
559
-
560
- it 'should know if it\'s a proper subset of another period' do
561
- year = Period.parse('this_year')
562
- month = Period.parse('this_month')
563
- expect(month.proper_subset_of?(year)).to be true
564
- expect(year.proper_subset_of?(year)).to be false
565
- end
566
-
567
- it 'should know if it\'s a superset of another period' do
568
- year = Period.parse('this_year')
569
- month = Period.parse('this_month')
570
- expect(year.superset_of?(month)).to be true
571
- expect(year.superset_of?(year)).to be true
572
- end
573
-
574
- it 'should know if it\'s a proper superset of another period' do
575
- year = Period.parse('this_year')
576
- month = Period.parse('this_month')
577
- expect(year.proper_superset_of?(month)).to be true
578
- expect(year.proper_superset_of?(year)).to be false
579
- end
580
-
581
- it 'should know if it overlaps another period' do
582
- period1 = Period.parse('2013')
583
- period2 = Period.parse('2012-10', '2013-03')
584
- period3 = Period.parse('2014')
585
- expect(period1.overlaps?(period2)).to be true
586
- expect(period2.overlaps?(period1)).to be true
587
- expect(period1.overlaps?(period3)).to be false
588
- end
589
-
590
- it 'should know whether an array of periods have overlaps within it' do
591
- months = (1..12).to_a.map { |k| Period.parse("2013-#{k}") }
592
- year = Period.parse('2013')
593
- expect(year.has_overlaps_within?(months)).to be false
594
- months << Period.parse('2013-09-15', '2013-10-02')
595
- expect(year.has_overlaps_within?(months)).to be true
596
- end
597
-
598
- it 'should know whether an array of periods span it' do
599
- months = (1..12).to_a.map { |k| Period.parse("2013-#{k}") }
600
- year = Period.parse('2013')
601
- expect(year.spanned_by?(months)).to be true
602
-
603
- months = (2..12).to_a.map { |k| Period.parse("2013-#{k}") }
604
- expect(year.spanned_by?(months)).to be false
605
- end
606
-
607
- it 'should know its intersection with other period' do
608
- year = Period.parse('this_year')
609
- month = Period.parse('this_month')
610
- expect(year & month).to eq(month)
611
- expect(month & year).to eq(month)
612
- # It should return a Period, not a Range
613
- expect((month & year).class).to eq(Period)
614
- end
615
-
616
- it 'should alias narrow_to to intersection' do
617
- period1 = Period.parse('2014')
618
- period2 = Period.new('2014-06-01', '2015-02-28')
619
- period3 = period1.narrow_to(period2)
620
- expect(period3.first).to eq(period2.first)
621
- expect(period3.last).to eq(period1.last)
622
- end
623
-
624
- it 'should return nil if no intersection' do
625
- year = Period.parse('2014')
626
- month = Period.parse('2013-05')
627
- expect(year & month).to be_nil
628
- end
629
-
630
- it 'should know its union with other period' do
631
- last_month = Period.parse('last_month')
632
- month = Period.parse('this_month')
633
- expect((last_month + month).first).to eq(last_month.first)
634
- expect((last_month + month).last).to eq(month.last)
635
- # It should return a Period, not a Range
636
- expect((last_month + month).class).to eq(Period)
637
- end
638
-
639
- it 'should know its differences with other period' do
640
- year = Period.parse('this_year')
641
- month = Period.parse('this_month')
642
- # Note: the difference operator returns an Array of Periods resulting
643
- # from removing other from self.
644
- expect((year - month).first)
645
- .to eq(Period.new(year.first, month.first - 1.day))
646
- expect((year - month).last)
647
- .to eq(Period.new(month.last + 1.day, year.last))
648
- # It should return an Array of Periods, not a Ranges
649
- (year - month).each do |p|
650
- expect(p.class).to eq(Period)
651
- end
652
-
653
- last_year = Period.parse('last_year')
654
- month = Period.parse('this_month')
655
- expect(last_year - month).to eq([last_year])
656
- end
657
-
658
- it 'should be able to find gaps from an array of periods' do
659
- pp = Period.parse('2014-2Q')
660
- periods = [
661
- Period.parse('2013-11', '2013-12-20'),
662
- Period.parse('2014-01', '2014-04-20'),
663
- # Gap 2014-04-21 to 2014-04-30
664
- Period.parse('2014-05', '2014-05-11'),
665
- # Gap 2014-05-12 to 2014-05-24
666
- Period.parse('2014-05-25', '2014-07-11'),
667
- Period.parse('2014-09')
668
- ]
669
- gaps = pp.gaps(periods)
670
- expect(gaps.size).to eq(2)
671
- expect(gaps.first.first).to eq(Date.parse('2014-04-21'))
672
- expect(gaps.first.last).to eq(Date.parse('2014-04-30'))
673
- expect(gaps.last.first).to eq(Date.parse('2014-05-12'))
674
- expect(gaps.last.last).to eq(Date.parse('2014-05-24'))
675
- end
676
- end
677
- end