timeboss 1.0.1 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/gem-push.yml +31 -0
  3. data/.github/workflows/ruby.yml +6 -4
  4. data/.travis.yml +11 -1
  5. data/Gemfile +2 -1
  6. data/README.md +7 -2
  7. data/Rakefile +3 -1
  8. data/bin/tbsh +7 -6
  9. data/lib/tasks/calendars.rake +4 -4
  10. data/lib/tasks/timeboss.rake +2 -2
  11. data/lib/timeboss/calendar/day.rb +3 -2
  12. data/lib/timeboss/calendar/half.rb +2 -1
  13. data/lib/timeboss/calendar/month.rb +2 -1
  14. data/lib/timeboss/calendar/parser.rb +9 -8
  15. data/lib/timeboss/calendar/period.rb +9 -6
  16. data/lib/timeboss/calendar/quarter.rb +2 -1
  17. data/lib/timeboss/calendar/support/formatter.rb +5 -4
  18. data/lib/timeboss/calendar/support/has_fiscal_weeks.rb +17 -0
  19. data/lib/timeboss/calendar/support/has_iso_weeks.rb +30 -0
  20. data/lib/timeboss/calendar/support/month_basis.rb +1 -1
  21. data/lib/timeboss/calendar/support/monthly_unit.rb +8 -8
  22. data/lib/timeboss/calendar/support/navigable.rb +2 -1
  23. data/lib/timeboss/calendar/support/shiftable.rb +12 -11
  24. data/lib/timeboss/calendar/support/translatable.rb +3 -2
  25. data/lib/timeboss/calendar/support/unit.rb +20 -13
  26. data/lib/timeboss/calendar/waypoints/absolute.rb +4 -3
  27. data/lib/timeboss/calendar/waypoints/relative.rb +14 -13
  28. data/lib/timeboss/calendar/week.rb +3 -2
  29. data/lib/timeboss/calendar/year.rb +2 -1
  30. data/lib/timeboss/calendar.rb +8 -7
  31. data/lib/timeboss/calendars/broadcast.rb +10 -7
  32. data/lib/timeboss/calendars/gregorian.rb +4 -5
  33. data/lib/timeboss/calendars.rb +3 -2
  34. data/lib/timeboss/version.rb +2 -1
  35. data/lib/timeboss.rb +2 -0
  36. data/spec/{calendar → lib/timeboss/calendar}/day_spec.rb +14 -14
  37. data/spec/{calendar → lib/timeboss/calendar}/quarter_spec.rb +9 -9
  38. data/spec/lib/timeboss/calendar/support/monthly_unit_spec.rb +91 -0
  39. data/spec/{calendar → lib/timeboss/calendar}/support/unit_spec.rb +23 -22
  40. data/spec/{calendar → lib/timeboss/calendar}/week_spec.rb +20 -20
  41. data/spec/lib/timeboss/calendars/broadcast_spec.rb +796 -0
  42. data/spec/lib/timeboss/calendars/gregorian_spec.rb +793 -0
  43. data/spec/{calendars_spec.rb → lib/timeboss/calendars_spec.rb} +19 -19
  44. data/spec/spec_helper.rb +2 -2
  45. data/timeboss.gemspec +17 -14
  46. metadata +53 -23
  47. data/spec/calendar/support/monthly_unit_spec.rb +0 -85
  48. data/spec/calendars/broadcast_spec.rb +0 -796
  49. data/spec/calendars/gregorian_spec.rb +0 -684
@@ -1,796 +0,0 @@
1
- module TimeBoss
2
- describe Calendars::Broadcast 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-03-27')
34
- expect(quarter.end_date).to eq Date.parse('2017-06-25')
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-06-25')
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-09-30')
56
- expect(quarter.end_date).to eq Date.parse('2019-12-29')
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-06-27 is in' do
63
- quarter = subject.quarter_for(Date.parse('2018-06-27'))
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-01-30')
166
- expect(month.end_date).to eq Date.parse('2017-02-26')
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-02-26')
177
- expect(month.end_date).to eq Date.parse('2018-03-25')
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-10-28')
188
- expect(month.end_date).to eq Date.parse('2019-11-24')
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-06-27 is in' do
195
- month = subject.month_for(Date.parse('2018-06-27'))
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
- before(:each) { allow(Date).to receive(:today).and_return Date.parse('2019-08-23') }
297
-
298
- it 'knows this week 'do
299
- expect(subject.this_week.name).to eq '2019W34'
300
- expect(subject.this_week.title).to eq 'Week of August 19, 2019'
301
- end
302
-
303
- it 'knows last week' do
304
- expect(subject.last_week.name).to eq '2019W33'
305
- expect(subject.last_week.title).to eq 'Week of August 12, 2019'
306
- end
307
-
308
- it 'knows next week' do
309
- expect(subject.next_week.name).to eq '2019W35'
310
- expect(subject.next_week.title).to eq 'Week of August 26, 2019'
311
- end
312
- end
313
-
314
- context 'years' do
315
- describe '#year' do
316
- it 'knows 2016' do
317
- year = subject.year(2016)
318
- expect(year.name).to eq '2016'
319
- expect(year.title).to eq '2016'
320
- expect(year.year_index).to eq 2016
321
- expect(year.index).to eq 1
322
- expect(year.start_date).to eq Date.parse('2015-12-28')
323
- expect(year.end_date).to eq Date.parse('2016-12-25')
324
- expect(year.to_range).to eq year.start_date..year.end_date
325
- end
326
-
327
- it 'knows 2017' do
328
- year = subject.year(2017)
329
- expect(year.name).to eq '2017'
330
- expect(year.title).to eq '2017'
331
- expect(year.year_index).to eq 2017
332
- expect(year.index).to eq 1
333
- expect(year.start_date).to eq Date.parse('2016-12-26')
334
- expect(year.end_date).to eq Date.parse('2017-12-31')
335
- expect(year.to_range).to eq year.start_date..year.end_date
336
- end
337
-
338
- it 'knows 2018' do
339
- year = subject.year(2018)
340
- expect(year.name).to eq '2018'
341
- expect(year.title).to eq '2018'
342
- expect(year.year_index).to eq 2018
343
- expect(year.index).to eq 1
344
- expect(year.start_date).to eq Date.parse('2018-01-01')
345
- expect(year.end_date).to eq Date.parse('2018-12-30')
346
- expect(year.to_range).to eq year.start_date..year.end_date
347
- end
348
- end
349
-
350
- describe '#year_for' do
351
- it 'knows what year 2018-04-07 is in' do
352
- year = subject.year_for(Date.parse('2018-04-07'))
353
- expect(year.name).to eq '2018'
354
- end
355
-
356
- it 'knows what year 2016-12-27 is in' do
357
- year = subject.year_for(Date.parse('2016-12-27'))
358
- expect(year.name).to eq '2017'
359
- end
360
- end
361
-
362
- describe '#years_for' do
363
- it 'knows what years are in 2020 (duh)' do
364
- basis = subject.year(2020)
365
- periods = subject.years_for(basis)
366
- expect(periods.map(&:name)).to eq %w[2020]
367
- end
368
-
369
- it 'knows what year 2018Q2 is in' do
370
- basis = subject.parse('2018Q2')
371
- periods = subject.years_for(basis)
372
- expect(periods.map(&:name)).to eq %w[2018]
373
- end
374
-
375
- it 'knows what years 2019-12-12 is in' do
376
- basis = subject.parse('2019-12-12')
377
- periods = subject.years_for(basis)
378
- expect(periods.map(&:name)).to eq %w[2019]
379
- end
380
- end
381
-
382
- describe '#this_year' do
383
- let(:today) { double }
384
- let(:year) { double }
385
-
386
- it 'gets the year for today' do
387
- allow(Date).to receive(:today).and_return today
388
- expect(subject).to receive(:year_for).with(today).and_return year
389
- expect(subject.this_year).to eq year
390
- end
391
- end
392
-
393
- describe '#format' do
394
- let(:entry) { subject.parse('2020W24') }
395
-
396
- it 'can do a default format' do
397
- expect(entry.format).to eq '2020H1Q2M3W2'
398
- end
399
-
400
- it 'can format with only the quarter' do
401
- expect(entry.format(:quarter)).to eq '2020Q2W11'
402
- end
403
-
404
- it 'can format with only the quarter + month' do
405
- expect(entry.format(:quarter, :month)).to eq '2020Q2M3W2'
406
- expect(entry.format(:month, :quarter)).to eq '2020Q2M3W2'
407
- end
408
-
409
- it 'ignores stupidity' do
410
- expect(entry.format(:day, :month, :banana)).to eq '2020M6W2'
411
- end
412
- end
413
-
414
- context 'relative' do
415
- let(:this_year) { subject.year(2015) }
416
- let(:year) { double }
417
- before(:each) { allow(subject).to receive(:this_year).and_return this_year }
418
-
419
- it 'can get the last year' do
420
- allow(this_year).to receive(:previous).and_return year
421
- expect(subject.last_year).to eq year
422
- end
423
-
424
- it 'can get the next year' do
425
- allow(this_year).to receive(:next).and_return year
426
- expect(subject.next_year).to eq year
427
- end
428
-
429
- it 'can get some number of years' do
430
- years = subject.years(5)
431
- expect(years.length).to eq 5
432
- years.each { |y| expect(y).to be_a TimeBoss::Calendar::Year }
433
- expect(years.map(&:name)).to eq ['2015', '2016', '2017', '2018', '2019']
434
- end
435
-
436
- it 'can get some number of years back' do
437
- years = subject.years_back(5)
438
- expect(years.length).to eq 5
439
- years.each { |y| expect(y).to be_a TimeBoss::Calendar::Year }
440
- expect(years.map(&:name)).to eq ['2011', '2012', '2013', '2014', '2015']
441
- end
442
- end
443
- end
444
-
445
- describe '#parse' do
446
- it 'can parse a year' do
447
- date = subject.parse('2018')
448
- expect(date).to be_a TimeBoss::Calendar::Year
449
- expect(date.name).to eq '2018'
450
- end
451
-
452
- it 'can parse a quarter identifier' do
453
- date = subject.parse('2017Q2')
454
- expect(date).to be_a TimeBoss::Calendar::Quarter
455
- expect(date.name).to eq '2017Q2'
456
- end
457
-
458
- it 'can parse a month identifier' do
459
- date = subject.parse('2017M4')
460
- expect(date).to be_a TimeBoss::Calendar::Month
461
- expect(date.name).to eq '2017M4'
462
- end
463
-
464
- it 'can parse a week within a year' do
465
- date = subject.parse('2018W37')
466
- expect(date).to be_a TimeBoss::Calendar::Week
467
- expect(date.name).to eq '2018W37'
468
- end
469
-
470
- it 'can parse a week within a quarter' do
471
- date = subject.parse('2017Q2W2')
472
- expect(date).to be_a TimeBoss::Calendar::Week
473
- expect(date.name).to eq '2017W15'
474
- end
475
-
476
- it 'can parse a week within a month' do
477
- date = subject.parse('2017M4W1')
478
- expect(date).to be_a TimeBoss::Calendar::Week
479
- expect(date.name).to eq '2017W14'
480
- end
481
-
482
- it 'can parse a date' do
483
- date = subject.parse('2017-04-08')
484
- expect(date).to be_a TimeBoss::Calendar::Day
485
- expect(date.start_date).to eq Date.parse('2017-04-08')
486
- expect(date.end_date).to eq Date.parse('2017-04-08')
487
- end
488
-
489
- it 'can parse an aesthetically displeasing date' do
490
- date = subject.parse('20170408')
491
- expect(date).to be_a TimeBoss::Calendar::Day
492
- expect(date.start_date).to eq Date.parse('2017-04-08')
493
- expect(date.end_date).to eq Date.parse('2017-04-08')
494
- end
495
-
496
- it 'gives you nothing if you give it nothing' do
497
- expect(subject.parse(nil)).to be nil
498
- expect(subject.parse('')).to be nil
499
- end
500
- end
501
-
502
- context 'expressions' do
503
- it 'can parse waypoints' do
504
- result = subject.parse('this_year')
505
- expect(result).to be_a TimeBoss::Calendar::Year
506
- expect(result).to be_current
507
- end
508
-
509
- it 'can parse mathematic expressions' do
510
- result = subject.parse('this_month + 2')
511
- expect(result).to be_a TimeBoss::Calendar::Month
512
- expect(result).to eq subject.months_ahead(2)
513
- end
514
-
515
- context 'ranges' do
516
- before(:each) { allow(subject).to receive(:this_year).and_return subject.year(2018) }
517
- let(:result) { subject.parse('this_year-2 .. this_year') }
518
-
519
- it 'can parse range expressions' do
520
- expect(result).to be_a TimeBoss::Calendar::Period
521
- expect(result.to_s).to eq "2016: 2015-12-28 thru 2016-12-25 .. 2018: 2018-01-01 thru 2018-12-30"
522
- end
523
-
524
- it 'can get an overall start date for a range' do
525
- expect(result.start_date).to eq Date.parse('2015-12-28')
526
- end
527
-
528
- it 'can get an overall end date for a range' do
529
- expect(result.end_date).to eq Date.parse('2018-12-30')
530
- end
531
-
532
- context 'sub-periods' do
533
- it 'can get the months included in a range' do
534
- entries = result.months
535
- entries.each { |e| expect(e).to be_a TimeBoss::Calendar::Month }
536
- expect(entries.map(&:name)).to include('2016M1', '2016M9', '2017M3', '2018M12')
537
- end
538
-
539
- it 'can get the weeks included in a range' do
540
- entries = result.weeks
541
- entries.each { |e| expect(e).to be_a TimeBoss::Calendar::Week }
542
- expect(entries.map(&:name)).to include('2016W1', '2016W38', '2017W15', '2017W53', '2018W52')
543
- end
544
-
545
- it 'can get the days included in a range' do
546
- entries = result.days
547
- entries.each { |e| expect(e).to be_a TimeBoss::Calendar::Day }
548
- expect(entries.map(&:name)).to include('2015-12-28', '2016-04-30', '2017-09-22', '2018-12-30')
549
- end
550
- end
551
- end
552
- end
553
-
554
- context 'shifting' do
555
- context 'from day' do
556
- let(:basis) { subject.parse('2020-04-21') }
557
-
558
- it 'can shift to a different week' do
559
- allow(subject).to receive(:this_week).and_return subject.parse('2020W23')
560
- result = basis.last_week
561
- expect(result).to be_a TimeBoss::Calendar::Day
562
- expect(result.to_s).to eq '2020-05-26'
563
- expect(basis.in_week).to eq 2
564
- end
565
-
566
- it 'can shift to a different quarter' do
567
- allow(subject).to receive(:this_quarter).and_return subject.parse('2020Q3')
568
- result = basis.quarters_ago(2)
569
- expect(result).to be_a TimeBoss::Calendar::Day
570
- expect(result.to_s).to eq '2020-01-21'
571
- expect(basis.in_quarter).to eq 23
572
- end
573
-
574
- it 'can shift to a different year' do
575
- allow(subject).to receive(:this_year).and_return subject.parse('2019')
576
- result = basis.years_ahead(3)
577
- expect(result).to be_a TimeBoss::Calendar::Day
578
- expect(result.to_s).to eq '2022-04-19'
579
- expect(basis.in_year).to eq 114
580
- end
581
- end
582
-
583
- context 'from week' do
584
- let(:basis) { subject.parse('2017W8') }
585
-
586
- it 'cannot shift to a different day' do
587
- expect(basis.last_day).to be nil
588
- expect(basis.in_day).to be nil
589
- end
590
-
591
- it 'can shift to a different month' do
592
- allow(subject).to receive(:this_month).and_return subject.parse('2020M4')
593
- result = basis.next_month
594
- expect(result).to be_a TimeBoss::Calendar::Week
595
- expect(result.to_s).to eq '2020W20: 2020-05-11 thru 2020-05-17'
596
- expect(basis.in_month).to eq 3
597
- end
598
-
599
- it 'can shift to a different half' do
600
- allow(subject).to receive(:this_half).and_return subject.parse('2019H1')
601
- result = basis.last_half
602
- expect(result).to be_a TimeBoss::Calendar::Week
603
- expect(result.to_s).to eq '2018W33: 2018-08-13 thru 2018-08-19'
604
- expect(basis.in_half).to eq 8
605
- end
606
- end
607
-
608
- context 'from month' do
609
- let(:basis) { subject.parse('2017M4') }
610
-
611
- it 'cannot shift to a different week' do
612
- expect(basis.last_week).to be nil
613
- expect(basis.in_week).to be nil
614
- end
615
-
616
- it 'can shift to a different year' do
617
- allow(subject).to receive(:this_year).and_return subject.parse('2020')
618
- result = basis.years_ahead(4)
619
- expect(result).to be_a TimeBoss::Calendar::Month
620
- expect(result.name).to eq '2024M4'
621
- expect(basis.in_year).to eq 4
622
- end
623
- end
624
-
625
- context 'from quarter' do
626
- let(:basis) { subject.parse('2018Q2') }
627
-
628
- it 'cannot shift to a different month' do
629
- expect(basis.months_ago(4)).to be nil
630
- expect(basis.in_month).to be nil
631
- end
632
-
633
- it 'can shift to a different half' do
634
- allow(subject).to receive(:this_half).and_return subject.parse('2020H1')
635
- result = basis.last_half
636
- expect(result).to be_a TimeBoss::Calendar::Quarter
637
- expect(result.name).to eq '2019Q4'
638
- expect(basis.in_half).to eq 2
639
- end
640
- end
641
-
642
- context 'from year' do
643
- let(:basis) { subject.parse('2014') }
644
-
645
- it 'cannot shift to a different half' do
646
- expect(basis.next_half).to be nil
647
- expect(basis.in_half).to be nil
648
- end
649
-
650
- it 'shifts to a different year, but knows how useless that is' do
651
- allow(subject).to receive(:this_year).and_return subject.parse('2020')
652
- result = basis.years_ago(2)
653
- expect(result).to be_a TimeBoss::Calendar::Year
654
- expect(result.name).to eq '2018'
655
- expect(basis.in_year).to eq 1
656
- end
657
- end
658
- end
659
-
660
- context 'units' do
661
- let(:calendar) { described_class.new }
662
-
663
- context 'day' do
664
- let(:start_date) { Date.parse('2019-09-30') }
665
- let(:subject) { TimeBoss::Calendar::Day.new(calendar, start_date) }
666
-
667
- context 'links' do
668
- it 'can get its previous' do
669
- expect(subject.previous.name).to eq '2019-09-29'
670
- end
671
-
672
- it 'can get its next' do
673
- expect(subject.next.name).to eq '2019-10-01'
674
- end
675
-
676
- it 'can offset backwards' do
677
- expect(subject.offset(-3).name).to eq '2019-09-27'
678
- expect((subject - 3).name).to eq '2019-09-27'
679
- end
680
-
681
- it 'can offset forwards' do
682
- expect(subject.offset(4).name).to eq '2019-10-04'
683
- expect((subject + 4).name).to eq '2019-10-04'
684
- end
685
- end
686
- end
687
-
688
- context 'week' do
689
- context 'links' do
690
- context 'within year' do
691
- let(:parent) { calendar.parse('2020') }
692
- let(:week) { parent.weeks.first }
693
-
694
- it 'knows itself first' do
695
- expect(week.to_s).to include('2020W1', '2019-12-30', '2020-01-05')
696
- end
697
-
698
- it 'can get its next week' do
699
- subject = week.next
700
- expect(subject).to be_a TimeBoss::Calendar::Week
701
- expect(subject.to_s).to include('2020W2', '2020-01-06', '2020-01-12')
702
- end
703
-
704
- it 'can get its previous week' do
705
- subject = week.previous
706
- expect(subject).to be_a TimeBoss::Calendar::Week
707
- expect(subject.to_s).to include('2019W52', '2019-12-23', '2019-12-29')
708
- end
709
-
710
- it 'can offset backwards' do
711
- expect(week.offset(-4).name).to eq '2019W49'
712
- expect((week - 4).name).to eq '2019W49'
713
- end
714
-
715
- it 'can offset forwards' do
716
- expect((week + 2).name).to eq '2020W3'
717
- end
718
- end
719
-
720
- context 'within quarter' do
721
- let(:parent) { calendar.parse('2019Q3') }
722
- let(:week) { parent.weeks.last }
723
-
724
- it 'knows itself first' do
725
- expect(week.to_s).to include('2019W39', '2019-09-23', '2019-09-29')
726
- end
727
-
728
- it 'can get its next week' do
729
- subject = week.next
730
- expect(subject).to be_a TimeBoss::Calendar::Week
731
- expect(subject.to_s).to include('2019W40', '2019-09-30', '2019-10-06')
732
- end
733
-
734
- it 'can get its previous week' do
735
- subject = week.previous
736
- expect(subject).to be_a TimeBoss::Calendar::Week
737
- expect(subject.to_s).to include('2019W38', '2019-09-16', '2019-09-22')
738
- end
739
-
740
- it 'can offset backwards' do
741
- expect(week.offset(-4).name).to eq '2019W35'
742
- expect((week - 4).name).to eq '2019W35'
743
- end
744
-
745
- it 'can offset forwards' do
746
- expect((week + 2).name).to eq '2019W41'
747
- end
748
- end
749
- end
750
- end
751
-
752
- context 'quarter' do
753
- let(:start_date) { Date.parse('2019-09-30') }
754
- let(:end_date) { Date.parse('2019-12-29') }
755
- let(:subject) { TimeBoss::Calendar::Quarter.new(calendar, 2019, 4, start_date, end_date) }
756
-
757
- context 'links' do
758
- it 'can get the next quarter' do
759
- quarter = subject.next
760
- expect(quarter.to_s).to include('2020Q1', '2019-12-30', '2020-03-29')
761
- end
762
-
763
- it 'can get the next next quarter' do
764
- quarter = subject.next.next
765
- expect(quarter.to_s).to include('2020Q2', '2020-03-30', '2020-06-28')
766
- end
767
-
768
- it 'can get the next next previous quarter' do
769
- quarter = subject.next.next.previous
770
- expect(quarter.to_s).to include('2020Q1', '2019-12-30', '2020-03-29')
771
- end
772
-
773
- it 'can get the next previous quarter' do
774
- quarter = subject.next.previous
775
- expect(quarter.to_s).to eq subject.to_s
776
- end
777
-
778
- it 'can get the previous quarter' do
779
- quarter = subject.previous
780
- expect(quarter.to_s).to include('2019Q3', '2019-07-01', '2019-09-29')
781
- end
782
-
783
- it 'can offset backwards' do
784
- expect(subject.offset(-4).name).to eq '2018Q4'
785
- expect((subject - 4).name).to eq '2018Q4'
786
- end
787
-
788
- it 'can offset forwards' do
789
- expect(subject.offset(2).name).to eq '2020Q2'
790
- expect((subject + 2).name).to eq '2020Q2'
791
- end
792
- end
793
- end
794
- end
795
- end
796
- end