timeboss 0.2.1 → 0.2.2
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.
- checksums.yaml +4 -4
- data/lib/timeboss/calendar.rb +5 -1
- data/lib/timeboss/calendars/broadcast.rb +0 -4
- data/lib/timeboss/calendars/gregorian.rb +4 -0
- data/lib/timeboss/version.rb +1 -1
- data/spec/calendars/gregorian_spec.rb +685 -0
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9d4c953bb1ef449bdc7d37f0ac3061da752b28a9f4df8c1901f9507c447ac89b
|
4
|
+
data.tar.gz: 752abd38f0afee607b6529894eec4189dfbbc462f5a27ddb4a6238720db35b4e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b1d04714bcb3514b386fda20f1aaad42f1db96382719848ef9ee5cf889b5c855a26bbb6c6039f50e08ce2484194924ceb8a2ee32f0242b1e3bbc928a9156a0b8
|
7
|
+
data.tar.gz: 1662c699fc80d9b37744a2f7f4fffa5d72e64d912bab4e19b1d113ba466a16201c003e32b26d1d8697da8c2feb21d4e16be344bc2bacdb2358f2a46ed6646c49
|
data/lib/timeboss/calendar.rb
CHANGED
@@ -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
|
-
|
40
|
+
true
|
37
41
|
end
|
38
42
|
|
39
43
|
protected
|
data/lib/timeboss/version.rb
CHANGED
@@ -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.
|
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
|