timeboss 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1e9e42e59807ef4268bea48fffb572839eca05a8ae52309990ccb478c1431c42
4
- data.tar.gz: 7077b857d5d72786cb092cf329f422bc1f7f7868a54e970164f8c7834a00c3c2
3
+ metadata.gz: 9d4c953bb1ef449bdc7d37f0ac3061da752b28a9f4df8c1901f9507c447ac89b
4
+ data.tar.gz: 752abd38f0afee607b6529894eec4189dfbbc462f5a27ddb4a6238720db35b4e
5
5
  SHA512:
6
- metadata.gz: 7e50564efbd452f31fc7bf7939c3a0cb458aff1fd68d4279187efc013a65dad05e5ec88acf3957fe8f54874d6f795dd4e3c05aecb0199df7117ea105a4b03225
7
- data.tar.gz: 102c86505d6ef3b5f152b76a865d3379d5e07200e01f5c02f9ea82a830b903d503398f804bc530fc439a1a90d374e878386f825137477a3dfb59c5e735fe8acd
6
+ metadata.gz: b1d04714bcb3514b386fda20f1aaad42f1db96382719848ef9ee5cf889b5c855a26bbb6c6039f50e08ce2484194924ceb8a2ee32f0242b1e3bbc928a9156a0b8
7
+ data.tar.gz: 1662c699fc80d9b37744a2f7f4fffa5d72e64d912bab4e19b1d113ba466a16201c003e32b26d1d8697da8c2feb21d4e16be344bc2bacdb2358f2a46ed6646c49
@@ -32,8 +32,12 @@ module TimeBoss
32
32
  name.titleize
33
33
  end
34
34
 
35
+ # Can this calendar support weeks?
36
+ # For custom calendars, this value can generally not be overridden.
37
+ # But for calendars like our Gregorian implementation, weeks are irrelevant, and should be suppressed.
38
+ # @return [Boolean]
35
39
  def supports_weeks?
36
- false
40
+ true
37
41
  end
38
42
 
39
43
  protected
@@ -8,10 +8,6 @@ module TimeBoss
8
8
  super(basis: Basis)
9
9
  end
10
10
 
11
- def supports_weeks?
12
- true
13
- end
14
-
15
11
  private
16
12
 
17
13
  class Basis < Calendar::Support::MonthBasis
@@ -8,6 +8,10 @@ module TimeBoss
8
8
  super(basis: Basis)
9
9
  end
10
10
 
11
+ def supports_weeks?
12
+ false
13
+ end
14
+
11
15
  private
12
16
 
13
17
  class Basis < Calendar::Support::MonthBasis
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module TimeBoss
3
- VERSION = "0.2.1"
3
+ VERSION = "0.2.2"
4
4
  end
@@ -0,0 +1,685 @@
1
+ module TimeBoss
2
+ describe Calendars::Gregorian do
3
+ let(:subject) { described_class.new }
4
+
5
+ context 'days' do
6
+ it 'can get today' do
7
+ day = subject.today
8
+ expect(day).to be_instance_of(TimeBoss::Calendar::Day)
9
+ expect(day.start_date).to eq Date.today
10
+ end
11
+
12
+ it 'can get yesterday' do
13
+ day = subject.yesterday
14
+ expect(day).to be_instance_of(TimeBoss::Calendar::Day)
15
+ expect(day.start_date).to eq Date.yesterday
16
+ end
17
+
18
+ it 'can get tomorrow' do
19
+ day = subject.tomorrow
20
+ expect(day).to be_instance_of(TimeBoss::Calendar::Day)
21
+ expect(day.start_date).to eq Date.tomorrow
22
+ end
23
+ end
24
+
25
+ context 'quarters' do
26
+ describe '#quarter' do
27
+ it 'knows 2017Q2' do
28
+ quarter = subject.quarter(2017, 2)
29
+ expect(quarter.name).to eq '2017Q2'
30
+ expect(quarter.title).to eq 'Q2 2017'
31
+ expect(quarter.year_index).to eq 2017
32
+ expect(quarter.index).to eq 2
33
+ expect(quarter.start_date).to eq Date.parse('2017-04-01')
34
+ expect(quarter.end_date).to eq Date.parse('2017-06-30')
35
+ expect(quarter.to_range).to eq quarter.start_date..quarter.end_date
36
+ end
37
+
38
+ it 'knows 2018Q3' do
39
+ quarter = subject.quarter(2018, 3)
40
+ expect(quarter.name).to eq '2018Q3'
41
+ expect(quarter.title).to eq 'Q3 2018'
42
+ expect(quarter.year_index).to eq 2018
43
+ expect(quarter.index).to eq 3
44
+ expect(quarter.start_date).to eq Date.parse('2018-07-01')
45
+ expect(quarter.end_date).to eq Date.parse('2018-09-30')
46
+ expect(quarter.to_range).to eq quarter.start_date..quarter.end_date
47
+ end
48
+
49
+ it 'knows 2019Q4' do
50
+ quarter = subject.quarter(2019, 4)
51
+ expect(quarter.year_index).to eq 2019
52
+ expect(quarter.index).to eq 4
53
+ expect(quarter.name).to eq '2019Q4'
54
+ expect(quarter.title).to eq 'Q4 2019'
55
+ expect(quarter.start_date).to eq Date.parse('2019-10-01')
56
+ expect(quarter.end_date).to eq Date.parse('2019-12-31')
57
+ expect(quarter.to_range).to eq quarter.start_date..quarter.end_date
58
+ end
59
+ end
60
+
61
+ describe '#quarter_for' do
62
+ it 'knows what quarter 2018-07-05 is in' do
63
+ quarter = subject.quarter_for(Date.parse('2018-07-05'))
64
+ expect(quarter.name).to eq '2018Q3'
65
+ end
66
+
67
+ it 'knows what quarter 2018-06-22 is in' do
68
+ quarter = subject.quarter_for(Date.parse('2018-06-22'))
69
+ expect(quarter.name).to eq '2018Q2'
70
+ end
71
+ end
72
+
73
+ describe '#quarters_for' do
74
+ it 'knows what quarters are in 2020' do
75
+ basis = subject.year(2020)
76
+ periods = subject.quarters_for(basis)
77
+ expect(periods.map(&:name)).to eq %w[2020Q1 2020Q2 2020Q3 2020Q4]
78
+ end
79
+
80
+ it 'knows what quarter 2018M7 is in' do
81
+ basis = subject.month(2018, 7)
82
+ periods = subject.quarters_for(basis)
83
+ expect(periods.map(&:name)).to eq %w[2018Q3]
84
+ end
85
+ end
86
+
87
+ describe '#this_quarter' do
88
+ let(:today) { double }
89
+ let(:quarter) { double }
90
+
91
+ it 'gets the quarter for today' do
92
+ allow(Date).to receive(:today).and_return today
93
+ expect(subject).to receive(:quarter_for).with(today).and_return quarter
94
+ expect(subject.this_quarter).to eq quarter
95
+ end
96
+ end
97
+
98
+ describe '#format' do
99
+ let(:entry) { subject.quarter(2015, 3) }
100
+
101
+ it 'can do a default format' do
102
+ expect(entry.format).to eq '2015H2Q1'
103
+ end
104
+
105
+ it 'can format with only the quarter' do
106
+ expect(entry.format(:quarter)).to eq '2015Q3'
107
+ end
108
+
109
+ it 'ignores stupidity' do
110
+ expect(entry.format(:day, :banana)).to eq '2015Q3'
111
+ end
112
+ end
113
+
114
+ context 'relative' do
115
+ let(:this_quarter) { subject.quarter(2015, 3) }
116
+ let(:quarter) { double }
117
+ before(:each) { allow(subject).to receive(:this_quarter).and_return this_quarter }
118
+
119
+ it 'can get the last quarter' do
120
+ allow(this_quarter).to receive(:previous).and_return quarter
121
+ expect(subject.last_quarter).to eq quarter
122
+ end
123
+
124
+ it 'can get the next quarter' do
125
+ allow(this_quarter).to receive(:next).and_return quarter
126
+ expect(subject.next_quarter).to eq quarter
127
+ end
128
+
129
+ it 'can get some number of quarters' do
130
+ quarters = subject.quarters(5)
131
+ expect(quarters.length).to eq 5
132
+ quarters.each { |q| expect(q).to be_a TimeBoss::Calendar::Quarter }
133
+ expect(quarters.map(&:name)).to eq ['2015Q3', '2015Q4', '2016Q1', '2016Q2', '2016Q3']
134
+ end
135
+
136
+ it 'can get a quarter ahead' do
137
+ quarter = subject.quarters_ahead(4)
138
+ expect(quarter).to be_a TimeBoss::Calendar::Quarter
139
+ expect(quarter.name).to eq '2016Q3'
140
+ end
141
+
142
+ it 'can get some number of quarters back' do
143
+ quarters = subject.quarters_back(5)
144
+ expect(quarters.length).to eq 5
145
+ quarters.each { |q| expect(q).to be_a TimeBoss::Calendar::Quarter }
146
+ expect(quarters.map(&:name)).to eq ['2014Q3', '2014Q4', '2015Q1', '2015Q2', '2015Q3']
147
+ end
148
+
149
+ it 'can get a quarter ago' do
150
+ quarter = subject.quarters_ago(4)
151
+ expect(quarter).to be_a TimeBoss::Calendar::Quarter
152
+ expect(quarter.name).to eq '2014Q3'
153
+ end
154
+ end
155
+ end
156
+
157
+ context 'months' do
158
+ describe '#month' do
159
+ it 'knows 2017M2' do
160
+ month = subject.month(2017, 2)
161
+ expect(month.name).to eq '2017M2'
162
+ expect(month.title).to eq 'February 2017'
163
+ expect(month.year_index).to eq 2017
164
+ expect(month.index).to eq 2
165
+ expect(month.start_date).to eq Date.parse('2017-02-01')
166
+ expect(month.end_date).to eq Date.parse('2017-02-28')
167
+ expect(month.to_range).to eq month.start_date..month.end_date
168
+ end
169
+
170
+ it 'knows 2018M3' do
171
+ month = subject.month(2018, 3)
172
+ expect(month.name).to eq '2018M3'
173
+ expect(month.title).to eq 'March 2018'
174
+ expect(month.year_index).to eq 2018
175
+ expect(month.index).to eq 3
176
+ expect(month.start_date).to eq Date.parse('2018-03-01')
177
+ expect(month.end_date).to eq Date.parse('2018-03-31')
178
+ expect(month.to_range).to eq month.start_date..month.end_date
179
+ end
180
+
181
+ it 'knows 2019M11' do
182
+ month = subject.month(2019, 11)
183
+ expect(month.year_index).to eq 2019
184
+ expect(month.index).to eq 11
185
+ expect(month.name).to eq '2019M11'
186
+ expect(month.title).to eq 'November 2019'
187
+ expect(month.start_date).to eq Date.parse('2019-11-01')
188
+ expect(month.end_date).to eq Date.parse('2019-11-30')
189
+ expect(month.to_range).to eq month.start_date..month.end_date
190
+ end
191
+ end
192
+
193
+ describe '#month_for' do
194
+ it 'knows what month 2018-07-05 is in' do
195
+ month = subject.month_for(Date.parse('2018-07-05'))
196
+ expect(month.name).to eq '2018M7'
197
+ end
198
+
199
+ it 'knows what month 2018-06-22 is in' do
200
+ month = subject.month_for(Date.parse('2018-06-22'))
201
+ expect(month.name).to eq '2018M6'
202
+ end
203
+ end
204
+
205
+ describe '#months_for' do
206
+ it 'knows what months are in 2020' do
207
+ basis = subject.year(2020)
208
+ periods = subject.months_for(basis)
209
+ expect(periods.map(&:name)).to eq %w[2020M1 2020M2 2020M3 2020M4 2020M5 2020M6 2020M7 2020M8 2020M9 2020M10 2020M11 2020M12]
210
+ end
211
+
212
+ it 'knows what months are in 2018Q2' do
213
+ basis = subject.parse('2018Q2')
214
+ periods = subject.months_for(basis)
215
+ expect(periods.map(&:name)).to eq %w[2018M4 2018M5 2018M6]
216
+ end
217
+
218
+ it 'knows what month 2019-12-12 is in' do
219
+ basis = subject.parse('2019-12-12')
220
+ periods = subject.months_for(basis)
221
+ expect(periods.map(&:name)).to eq %w[2019M12]
222
+ end
223
+ end
224
+
225
+ describe '#this_month' do
226
+ let(:today) { double }
227
+ let(:month) { double }
228
+
229
+ it 'gets the month for today' do
230
+ allow(Date).to receive(:today).and_return today
231
+ expect(subject).to receive(:month_for).with(today).and_return month
232
+ expect(subject.this_month).to eq month
233
+ end
234
+ end
235
+
236
+ describe '#format' do
237
+ let(:entry) { subject.month(2015, 8) }
238
+
239
+ it 'can do a default format' do
240
+ expect(entry.format).to eq '2015H2Q1M2'
241
+ end
242
+
243
+ it 'can format with only the quarter' do
244
+ expect(entry.format(:quarter)).to eq '2015Q3M2'
245
+ end
246
+
247
+ it 'ignores stupidity' do
248
+ expect(entry.format(:banana, :half, :week)).to eq '2015H2M2'
249
+ end
250
+ end
251
+
252
+ context 'relative' do
253
+ let(:this_month) { subject.month(2015, 3) }
254
+ let(:month) { double }
255
+ before(:each) { allow(subject).to receive(:this_month).and_return this_month }
256
+
257
+ it 'can get the last month' do
258
+ allow(this_month).to receive(:previous).and_return month
259
+ expect(subject.last_month).to eq month
260
+ end
261
+
262
+ it 'can get the next month' do
263
+ allow(this_month).to receive(:next).and_return month
264
+ expect(subject.next_month).to eq month
265
+ end
266
+
267
+ it 'can get some number of months' do
268
+ months = subject.months(5)
269
+ expect(months.length).to eq 5
270
+ months.each { |m| expect(m).to be_a TimeBoss::Calendar::Month }
271
+ expect(months.map(&:name)).to eq ['2015M3', '2015M4', '2015M5', '2015M6', '2015M7']
272
+ end
273
+
274
+ it 'can get a month ahead' do
275
+ month = subject.months_ahead(4)
276
+ expect(month).to be_a TimeBoss::Calendar::Month
277
+ expect(month.name).to eq '2015M7'
278
+ end
279
+
280
+ it 'can get some number of months back' do
281
+ months = subject.months_back(5)
282
+ expect(months.length).to eq 5
283
+ months.each { |m| expect(m).to be_a TimeBoss::Calendar::Month }
284
+ expect(months.map(&:name)).to eq ['2014M11', '2014M12', '2015M1', '2015M2', '2015M3']
285
+ end
286
+
287
+ it 'can get a month ago' do
288
+ month = subject.months_ago(4)
289
+ expect(month).to be_a TimeBoss::Calendar::Month
290
+ expect(month.name).to eq '2014M11'
291
+ end
292
+ end
293
+ end
294
+
295
+ context 'weeks' do
296
+ it 'is uninterested in weeks' do
297
+ expect { subject.this_week }.to raise_error TimeBoss::Calendar::Support::Unit::UnsupportedUnitError
298
+ expect { subject.parse('2020W3') }.to raise_error TimeBoss::Calendar::Support::Unit::UnsupportedUnitError
299
+ expect { subject.weeks_ago(2) }.to raise_error TimeBoss::Calendar::Support::Unit::UnsupportedUnitError
300
+ end
301
+ end
302
+
303
+ context 'years' do
304
+ describe '#year' do
305
+ it 'knows 2016' do
306
+ year = subject.year(2016)
307
+ expect(year.name).to eq '2016'
308
+ expect(year.title).to eq '2016'
309
+ expect(year.year_index).to eq 2016
310
+ expect(year.index).to eq 1
311
+ expect(year.start_date).to eq Date.parse('2016-01-01')
312
+ expect(year.end_date).to eq Date.parse('2016-12-31')
313
+ expect(year.to_range).to eq year.start_date..year.end_date
314
+ end
315
+
316
+ it 'knows 2017' do
317
+ year = subject.year(2017)
318
+ expect(year.name).to eq '2017'
319
+ expect(year.title).to eq '2017'
320
+ expect(year.year_index).to eq 2017
321
+ expect(year.index).to eq 1
322
+ expect(year.start_date).to eq Date.parse('2017-01-01')
323
+ expect(year.end_date).to eq Date.parse('2017-12-31')
324
+ expect(year.to_range).to eq year.start_date..year.end_date
325
+ end
326
+
327
+ it 'knows 2018' do
328
+ year = subject.year(2018)
329
+ expect(year.name).to eq '2018'
330
+ expect(year.title).to eq '2018'
331
+ expect(year.year_index).to eq 2018
332
+ expect(year.index).to eq 1
333
+ expect(year.start_date).to eq Date.parse('2018-01-01')
334
+ expect(year.end_date).to eq Date.parse('2018-12-31')
335
+ expect(year.to_range).to eq year.start_date..year.end_date
336
+ end
337
+ end
338
+
339
+ describe '#year_for' do
340
+ it 'knows what year 2018-04-07 is in' do
341
+ year = subject.year_for(Date.parse('2018-04-07'))
342
+ expect(year.name).to eq '2018'
343
+ end
344
+
345
+ it 'knows what year 2016-12-27 is in' do
346
+ year = subject.year_for(Date.parse('2016-12-27'))
347
+ expect(year.name).to eq '2016'
348
+ end
349
+ end
350
+
351
+ describe '#years_for' do
352
+ it 'knows what years are in 2020 (duh)' do
353
+ basis = subject.year(2020)
354
+ periods = subject.years_for(basis)
355
+ expect(periods.map(&:name)).to eq %w[2020]
356
+ end
357
+
358
+ it 'knows what year 2018Q2 is in' do
359
+ basis = subject.parse('2018Q2')
360
+ periods = subject.years_for(basis)
361
+ expect(periods.map(&:name)).to eq %w[2018]
362
+ end
363
+
364
+ it 'knows what years 2019-12-12 is in' do
365
+ basis = subject.parse('2019-12-12')
366
+ periods = subject.years_for(basis)
367
+ expect(periods.map(&:name)).to eq %w[2019]
368
+ end
369
+ end
370
+
371
+ describe '#this_year' do
372
+ let(:today) { double }
373
+ let(:year) { double }
374
+
375
+ it 'gets the year for today' do
376
+ allow(Date).to receive(:today).and_return today
377
+ expect(subject).to receive(:year_for).with(today).and_return year
378
+ expect(subject.this_year).to eq year
379
+ end
380
+ end
381
+
382
+ describe '#format' do
383
+ let(:entry) { subject.parse('2020M8') }
384
+
385
+ it 'can do a default format' do
386
+ expect(entry.format).to eq '2020H2Q1M2'
387
+ end
388
+
389
+ it 'can format with only the quarter' do
390
+ expect(entry.format(:quarter)).to eq '2020Q3M2'
391
+ end
392
+
393
+ context 'with days' do
394
+ let(:entry) { subject.parse('2020D201') }
395
+
396
+ it 'can do a default format' do
397
+ expect(entry.format).to eq '2020H2Q1M1D19'
398
+ end
399
+ end
400
+ end
401
+
402
+ context 'relative' do
403
+ let(:this_year) { subject.year(2015) }
404
+ let(:year) { double }
405
+ before(:each) { allow(subject).to receive(:this_year).and_return this_year }
406
+
407
+ it 'can get the last year' do
408
+ allow(this_year).to receive(:previous).and_return year
409
+ expect(subject.last_year).to eq year
410
+ end
411
+
412
+ it 'can get the next year' do
413
+ allow(this_year).to receive(:next).and_return year
414
+ expect(subject.next_year).to eq year
415
+ end
416
+
417
+ it 'can get some number of years' do
418
+ years = subject.years(5)
419
+ expect(years.length).to eq 5
420
+ years.each { |y| expect(y).to be_a TimeBoss::Calendar::Year }
421
+ expect(years.map(&:name)).to eq ['2015', '2016', '2017', '2018', '2019']
422
+ end
423
+
424
+ it 'can get some number of years back' do
425
+ years = subject.years_back(5)
426
+ expect(years.length).to eq 5
427
+ years.each { |y| expect(y).to be_a TimeBoss::Calendar::Year }
428
+ expect(years.map(&:name)).to eq ['2011', '2012', '2013', '2014', '2015']
429
+ end
430
+ end
431
+ end
432
+
433
+ describe '#parse' do
434
+ it 'can parse a year' do
435
+ date = subject.parse('2018')
436
+ expect(date).to be_a TimeBoss::Calendar::Year
437
+ expect(date.name).to eq '2018'
438
+ end
439
+
440
+ it 'can parse a quarter identifier' do
441
+ date = subject.parse('2017Q2')
442
+ expect(date).to be_a TimeBoss::Calendar::Quarter
443
+ expect(date.name).to eq '2017Q2'
444
+ end
445
+
446
+ it 'can parse a month identifier' do
447
+ date = subject.parse('2017M4')
448
+ expect(date).to be_a TimeBoss::Calendar::Month
449
+ expect(date.name).to eq '2017M4'
450
+ end
451
+
452
+ it 'cannot parse a week within a year' do
453
+ expect { subject.parse('2018W37') }.to raise_error TimeBoss::Calendar::Support::Unit::UnsupportedUnitError
454
+ end
455
+
456
+ it 'cannot parse a week within a quarter' do
457
+ expect { subject.parse('2017Q2W2') }.to raise_error TimeBoss::Calendar::Support::Unit::UnsupportedUnitError
458
+ end
459
+
460
+ it 'cannot parse a week within a month' do
461
+ expect { subject.parse('2017M4W1') }.to raise_error TimeBoss::Calendar::Support::Unit::UnsupportedUnitError
462
+ end
463
+
464
+ it 'can parse a date' do
465
+ date = subject.parse('2017-04-08')
466
+ expect(date).to be_a TimeBoss::Calendar::Day
467
+ expect(date.start_date).to eq Date.parse('2017-04-08')
468
+ expect(date.end_date).to eq Date.parse('2017-04-08')
469
+ end
470
+
471
+ it 'can parse an aesthetically displeasing date' do
472
+ date = subject.parse('20170408')
473
+ expect(date).to be_a TimeBoss::Calendar::Day
474
+ expect(date.start_date).to eq Date.parse('2017-04-08')
475
+ expect(date.end_date).to eq Date.parse('2017-04-08')
476
+ end
477
+
478
+ it 'gives you this year if you give it nothing' do
479
+ year = subject.this_year
480
+ expect(subject.parse(nil)).to eq year
481
+ expect(subject.parse('')).to eq year
482
+ end
483
+ end
484
+
485
+ context 'expressions' do
486
+ it 'can parse waypoints' do
487
+ result = subject.parse('this_year')
488
+ expect(result).to be_a TimeBoss::Calendar::Year
489
+ expect(result).to be_current
490
+ end
491
+
492
+ it 'can parse mathematic expressions' do
493
+ result = subject.parse('this_month + 2')
494
+ expect(result).to be_a TimeBoss::Calendar::Month
495
+ expect(result).to eq subject.months_ahead(2)
496
+ end
497
+
498
+ context 'ranges' do
499
+ before(:each) { allow(subject).to receive(:this_year).and_return subject.year(2018) }
500
+ let(:result) { subject.parse('this_year-2 .. this_year') }
501
+
502
+ it 'can parse range expressions' do
503
+ expect(result).to be_a TimeBoss::Calendar::Period
504
+ expect(result.to_s).to eq "2016: 2016-01-01 thru 2016-12-31 .. 2018: 2018-01-01 thru 2018-12-31"
505
+ end
506
+
507
+ it 'can get an overall start date for a range' do
508
+ expect(result.start_date).to eq Date.parse('2016-01-01')
509
+ end
510
+
511
+ it 'can get an overall end date for a range' do
512
+ expect(result.end_date).to eq Date.parse('2018-12-31')
513
+ end
514
+
515
+ context 'sub-periods' do
516
+ it 'can get the months included in a range' do
517
+ entries = result.months
518
+ entries.each { |e| expect(e).to be_a TimeBoss::Calendar::Month }
519
+ expect(entries.map(&:name)).to include('2016M1', '2016M9', '2017M3', '2018M12')
520
+ end
521
+
522
+ it 'cannot get the weeks included in a range' do
523
+ expect { result.weeks }.to raise_error TimeBoss::Calendar::Support::Unit::UnsupportedUnitError
524
+ end
525
+
526
+ it 'can get the days included in a range' do
527
+ entries = result.days
528
+ entries.each { |e| expect(e).to be_a TimeBoss::Calendar::Day }
529
+ expect(entries.map(&:name)).to include('2016-01-01', '2016-05-12', '2017-09-22', '2018-12-31')
530
+ end
531
+ end
532
+ end
533
+ end
534
+
535
+ context 'shifting' do
536
+ context 'from day' do
537
+ let(:basis) { subject.parse('2020-04-21') }
538
+
539
+ it 'cannot shift to a different week' do
540
+ expect { basis.last_week }.to raise_error TimeBoss::Calendar::Support::Unit::UnsupportedUnitError
541
+ expect { basis.in_week }.to raise_error TimeBoss::Calendar::Support::Unit::UnsupportedUnitError
542
+ end
543
+
544
+ it 'can shift to a different quarter' do
545
+ allow(subject).to receive(:this_quarter).and_return subject.parse('2020Q3')
546
+ result = basis.quarters_ago(2)
547
+ expect(result).to be_a TimeBoss::Calendar::Day
548
+ expect(result.to_s).to eq '2020-01-21'
549
+ expect(basis.in_quarter).to eq 21
550
+ end
551
+
552
+ it 'can shift to a different year' do
553
+ allow(subject).to receive(:this_year).and_return subject.parse('2019')
554
+ result = basis.years_ahead(3)
555
+ expect(result).to be_a TimeBoss::Calendar::Day
556
+ expect(result.to_s).to eq '2022-04-22'
557
+ expect(basis.in_year).to eq 112
558
+ end
559
+ end
560
+
561
+ context 'from month' do
562
+ let(:basis) { subject.parse('2017M4') }
563
+
564
+ it 'cannot shift to a different week' do
565
+ expect { basis.last_week }.to raise_error TimeBoss::Calendar::Support::Unit::UnsupportedUnitError
566
+ expect { basis.in_week }.to raise_error TimeBoss::Calendar::Support::Unit::UnsupportedUnitError
567
+ end
568
+
569
+ it 'can shift to a different year' do
570
+ allow(subject).to receive(:this_year).and_return subject.parse('2020')
571
+ result = basis.years_ahead(4)
572
+ expect(result).to be_a TimeBoss::Calendar::Month
573
+ expect(result.name).to eq '2024M4'
574
+ expect(basis.in_year).to eq 4
575
+ end
576
+ end
577
+
578
+ context 'from quarter' do
579
+ let(:basis) { subject.parse('2018Q2') }
580
+
581
+ it 'cannot shift to a different month' do
582
+ expect(basis.months_ago(4)).to be nil
583
+ expect(basis.in_month).to be nil
584
+ end
585
+
586
+ it 'can shift to a different half' do
587
+ allow(subject).to receive(:this_half).and_return subject.parse('2020H1')
588
+ result = basis.last_half
589
+ expect(result).to be_a TimeBoss::Calendar::Quarter
590
+ expect(result.name).to eq '2019Q4'
591
+ expect(basis.in_half).to eq 2
592
+ end
593
+ end
594
+
595
+ context 'from year' do
596
+ let(:basis) { subject.parse('2014') }
597
+
598
+ it 'cannot shift to a different half' do
599
+ expect(basis.next_half).to be nil
600
+ expect(basis.in_half).to be nil
601
+ end
602
+
603
+ it 'shifts to a different year, but knows how useless that is' do
604
+ allow(subject).to receive(:this_year).and_return subject.parse('2020')
605
+ result = basis.years_ago(2)
606
+ expect(result).to be_a TimeBoss::Calendar::Year
607
+ expect(result.name).to eq '2018'
608
+ expect(basis.in_year).to eq 1
609
+ end
610
+ end
611
+ end
612
+
613
+ context 'units' do
614
+ let(:calendar) { described_class.new }
615
+
616
+ context 'day' do
617
+ let(:start_date) { Date.parse('2019-09-30') }
618
+ let(:subject) { TimeBoss::Calendar::Day.new(calendar, start_date) }
619
+
620
+ context 'links' do
621
+ it 'can get its previous' do
622
+ expect(subject.previous.name).to eq '2019-09-29'
623
+ end
624
+
625
+ it 'can get its next' do
626
+ expect(subject.next.name).to eq '2019-10-01'
627
+ end
628
+
629
+ it 'can offset backwards' do
630
+ expect(subject.offset(-3).name).to eq '2019-09-27'
631
+ expect((subject - 3).name).to eq '2019-09-27'
632
+ end
633
+
634
+ it 'can offset forwards' do
635
+ expect(subject.offset(4).name).to eq '2019-10-04'
636
+ expect((subject + 4).name).to eq '2019-10-04'
637
+ end
638
+ end
639
+ end
640
+
641
+ context 'quarter' do
642
+ let(:start_date) { Date.parse('2019-10-01') }
643
+ let(:end_date) { Date.parse('2019-12-31') }
644
+ let(:subject) { TimeBoss::Calendar::Quarter.new(calendar, 2019, 4, start_date, end_date) }
645
+
646
+ context 'links' do
647
+ it 'can get the next quarter' do
648
+ quarter = subject.next
649
+ expect(quarter.to_s).to include('2020Q1', '2020-01-01', '2020-03-31')
650
+ end
651
+
652
+ it 'can get the next next quarter' do
653
+ quarter = subject.next.next
654
+ expect(quarter.to_s).to include('2020Q2', '2020-04-01', '2020-06-30')
655
+ end
656
+
657
+ it 'can get the next next previous quarter' do
658
+ quarter = subject.next.next.previous
659
+ expect(quarter.to_s).to include('2020Q1', '2020-01-01', '2020-03-31')
660
+ end
661
+
662
+ it 'can get the next previous quarter' do
663
+ quarter = subject.next.previous
664
+ expect(quarter.to_s).to eq subject.to_s
665
+ end
666
+
667
+ it 'can get the previous quarter' do
668
+ quarter = subject.previous
669
+ expect(quarter.to_s).to include('2019Q3', '2019-07-01', '2019-09-30')
670
+ end
671
+
672
+ it 'can offset backwards' do
673
+ expect(subject.offset(-4).name).to eq '2018Q4'
674
+ expect((subject - 4).name).to eq '2018Q4'
675
+ end
676
+
677
+ it 'can offset forwards' do
678
+ expect(subject.offset(2).name).to eq '2020Q2'
679
+ expect((subject + 2).name).to eq '2020Q2'
680
+ end
681
+ end
682
+ end
683
+ end
684
+ end
685
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timeboss
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin McDonald
@@ -175,6 +175,7 @@ files:
175
175
  - spec/calendar/support/unit_spec.rb
176
176
  - spec/calendar/week_spec.rb
177
177
  - spec/calendars/broadcast_spec.rb
178
+ - spec/calendars/gregorian_spec.rb
178
179
  - spec/calendars_spec.rb
179
180
  - spec/spec_helper.rb
180
181
  - timeboss.gemspec
@@ -208,5 +209,6 @@ test_files:
208
209
  - spec/calendar/support/unit_spec.rb
209
210
  - spec/calendar/week_spec.rb
210
211
  - spec/calendars/broadcast_spec.rb
212
+ - spec/calendars/gregorian_spec.rb
211
213
  - spec/calendars_spec.rb
212
214
  - spec/spec_helper.rb