fat_core 4.11.0 → 4.12.1
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/.rubocop.yml +21 -15
- data/fat_core.gemspec +9 -5
- data/lib/fat_core/date.rb +38 -4
- data/lib/fat_core/string.rb +6 -67
- data/lib/fat_core/version.rb +2 -2
- data/spec/lib/array_spec.rb +1 -1
- data/spec/lib/bigdecimal_spec.rb +1 -1
- data/spec/lib/date_spec.rb +730 -660
- data/spec/lib/enumerable_spec.rb +8 -8
- data/spec/lib/hash_spec.rb +3 -3
- data/spec/lib/kernel_spec.rb +1 -1
- data/spec/lib/nil_spec.rb +3 -3
- data/spec/lib/numeric_spec.rb +10 -10
- data/spec/lib/range_spec.rb +39 -39
- data/spec/lib/string_spec.rb +137 -129
- data/spec/lib/symbol_spec.rb +3 -3
- metadata +13 -8
data/spec/lib/date_spec.rb
CHANGED
@@ -4,58 +4,58 @@ require 'spec_helper'
|
|
4
4
|
require 'fat_core/date'
|
5
5
|
|
6
6
|
describe Date do
|
7
|
-
before
|
7
|
+
before do
|
8
8
|
# Pretend it is this date. Not at beg or end of year, quarter,
|
9
9
|
# month, or week. It is a Wednesday
|
10
|
-
allow(
|
11
|
-
allow(
|
10
|
+
allow(described_class).to receive_messages(today: described_class.parse('2012-07-18'))
|
11
|
+
allow(described_class).to receive_messages(current: described_class.parse('2012-07-18'))
|
12
12
|
end
|
13
13
|
|
14
14
|
describe 'class methods' do
|
15
15
|
describe 'ensure_date parsing' do
|
16
|
-
it '
|
17
|
-
expect(
|
16
|
+
it 'parses a String as a date' do
|
17
|
+
expect(described_class.ensure_date('2018-11-12').class).to be described_class
|
18
18
|
end
|
19
19
|
|
20
|
-
it '
|
21
|
-
expect(
|
20
|
+
it 'leaves a Date as a date' do
|
21
|
+
expect(described_class.ensure_date(described_class.today).class).to be described_class
|
22
22
|
end
|
23
23
|
|
24
|
-
it '
|
25
|
-
expect(
|
24
|
+
it 'converts Time as a date' do
|
25
|
+
expect(described_class.ensure_date(Time.now).class).to be described_class
|
26
26
|
end
|
27
27
|
|
28
28
|
it 'raises an error for bad date string' do
|
29
|
-
expect {
|
29
|
+
expect { described_class.ensure_date('2012-mm-tu') }.to raise_error(/invalid date/)
|
30
30
|
end
|
31
31
|
|
32
32
|
it 'raises an error for unknown class' do
|
33
|
-
expect {
|
34
|
-
.to raise_error
|
33
|
+
expect { described_class.ensure_date([2011, 11, 12]) }
|
34
|
+
.to raise_error(/requires String, Date, DateTime, or Time/)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
38
|
describe 'date arithmetic' do
|
39
|
-
it '
|
40
|
-
expect(
|
41
|
-
expect(
|
42
|
-
expect(
|
43
|
-
expect(
|
44
|
-
expect(
|
45
|
-
expect(
|
46
|
-
expect(
|
47
|
-
expect(
|
48
|
-
expect(
|
49
|
-
expect(
|
50
|
-
expect(
|
51
|
-
expect(
|
52
|
-
expect(
|
53
|
-
expect(
|
54
|
-
expect(
|
55
|
-
expect {
|
56
|
-
end
|
57
|
-
|
58
|
-
it '
|
39
|
+
it 'knows the number of days in a month' do
|
40
|
+
expect(described_class.days_in_month(2000, 1)).to eq 31
|
41
|
+
expect(described_class.days_in_month(1900, 2)).to eq 28
|
42
|
+
expect(described_class.days_in_month(2000, 2)).to eq 29
|
43
|
+
expect(described_class.days_in_month(2001, 2)).to eq 28
|
44
|
+
expect(described_class.days_in_month(2004, 2)).to eq 29
|
45
|
+
expect(described_class.days_in_month(2004, 3)).to eq 31
|
46
|
+
expect(described_class.days_in_month(2004, 4)).to eq 30
|
47
|
+
expect(described_class.days_in_month(2004, 5)).to eq 31
|
48
|
+
expect(described_class.days_in_month(2004, 6)).to eq 30
|
49
|
+
expect(described_class.days_in_month(2004, 7)).to eq 31
|
50
|
+
expect(described_class.days_in_month(2004, 8)).to eq 31
|
51
|
+
expect(described_class.days_in_month(2004, 9)).to eq 30
|
52
|
+
expect(described_class.days_in_month(2004, 10)).to eq 31
|
53
|
+
expect(described_class.days_in_month(2004, 11)).to eq 30
|
54
|
+
expect(described_class.days_in_month(2004, 12)).to eq 31
|
55
|
+
expect { described_class.days_in_month(2004, 13) }.to raise_error(ArgumentError)
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'knows the nth weekday in a year, month' do
|
59
59
|
# Sunday is 0, Saturday is 6
|
60
60
|
# January 2014
|
61
61
|
# Su Mo Tu We Th Fr Sa
|
@@ -66,42 +66,42 @@ describe Date do
|
|
66
66
|
# 26 27 28 29 30 31
|
67
67
|
|
68
68
|
# First Monday
|
69
|
-
expect(
|
70
|
-
.to eq
|
69
|
+
expect(described_class.nth_wday_in_year_month(1, 1, 2014, 1))
|
70
|
+
.to eq described_class.parse('2014-01-06')
|
71
71
|
# Second Monday
|
72
|
-
expect(
|
73
|
-
.to eq
|
72
|
+
expect(described_class.nth_wday_in_year_month(2, 1, 2014, 1))
|
73
|
+
.to eq described_class.parse('2014-01-13')
|
74
74
|
# Third Sunday
|
75
|
-
expect(
|
76
|
-
.to eq
|
75
|
+
expect(described_class.nth_wday_in_year_month(3, 0, 2014, 1))
|
76
|
+
.to eq described_class.parse('2014-01-19')
|
77
77
|
# Third Sunday (float floored)
|
78
|
-
expect(
|
79
|
-
.to eq
|
78
|
+
expect(described_class.nth_wday_in_year_month(3.2, 0, 2014, 1))
|
79
|
+
.to eq described_class.parse('2014-01-19')
|
80
80
|
# Negative wday counts from end: Last Sunday
|
81
|
-
expect(
|
82
|
-
.to eq
|
83
|
-
expect(
|
84
|
-
.to eq
|
81
|
+
expect(described_class.nth_wday_in_year_month(-1, 0, 2014, 1))
|
82
|
+
.to eq described_class.parse('2014-01-26')
|
83
|
+
expect(described_class.nth_wday_in_year_month(-3, 0, 2014, 1))
|
84
|
+
.to eq described_class.parse('2014-01-12')
|
85
85
|
# Negative wday counts from end: Last Thursday
|
86
|
-
expect(
|
87
|
-
.to eq
|
86
|
+
expect(described_class.nth_wday_in_year_month(-1, 4, 2014, 1))
|
87
|
+
.to eq described_class.parse('2014-01-30')
|
88
88
|
|
89
89
|
# Exceptions
|
90
90
|
expect {
|
91
91
|
# N is zero
|
92
|
-
|
92
|
+
described_class.nth_wday_in_year_month(0, 6, 2014, 1)
|
93
93
|
}.to raise_error(ArgumentError)
|
94
94
|
expect {
|
95
95
|
# Wday too big
|
96
|
-
|
96
|
+
described_class.nth_wday_in_year_month(3, 7, 2014, 1)
|
97
97
|
}.to raise_error(ArgumentError)
|
98
98
|
expect {
|
99
99
|
# Month too big
|
100
|
-
|
100
|
+
described_class.nth_wday_in_year_month(3, 1, 2014, 13)
|
101
101
|
}.to raise_error(ArgumentError)
|
102
102
|
end
|
103
103
|
|
104
|
-
it '
|
104
|
+
it 'knows Easter for a given year' do
|
105
105
|
# Grabbed these dates of Easter from
|
106
106
|
# http://tlarsen2.tripod.com/thomaslarsen/easterdates.html
|
107
107
|
easters = {
|
@@ -207,21 +207,21 @@ describe Date do
|
|
207
207
|
2099 => '2099-04-12'
|
208
208
|
}
|
209
209
|
easters.each_pair do |year, date|
|
210
|
-
expect(
|
210
|
+
expect(described_class.easter(year)).to eq described_class.parse(date)
|
211
211
|
end
|
212
212
|
end
|
213
213
|
end
|
214
214
|
|
215
215
|
describe 'parsing' do
|
216
|
-
it '
|
217
|
-
expect(
|
218
|
-
expect(
|
219
|
-
expect(
|
220
|
-
expect(
|
221
|
-
expect(
|
222
|
-
expect(
|
216
|
+
it 'parses an American-style date' do
|
217
|
+
expect(described_class.parse_american('2/12/2011').iso).to eq('2011-02-12')
|
218
|
+
expect(described_class.parse_american('2 / 12/ 2011').iso).to eq('2011-02-12')
|
219
|
+
expect(described_class.parse_american('2 / 1 / 2011').iso).to eq('2011-02-01')
|
220
|
+
expect(described_class.parse_american(' 2 / 1 / 2011 ').iso).to eq('2011-02-01')
|
221
|
+
expect(described_class.parse_american(' 2 / 1 / 15 ').iso).to eq('2015-02-01')
|
222
|
+
expect(described_class.parse_american(' 2-1-15 ').iso).to eq('2015-02-01')
|
223
223
|
expect {
|
224
|
-
|
224
|
+
described_class.parse_american('xx/1/15')
|
225
225
|
}.to raise_error(ArgumentError)
|
226
226
|
end
|
227
227
|
end
|
@@ -229,624 +229,682 @@ describe Date do
|
|
229
229
|
describe 'parse_spec' do
|
230
230
|
# For these tests, today is 2012-07-18
|
231
231
|
|
232
|
-
it '
|
232
|
+
it 'chokes if spec type is neither :from or :to' do
|
233
233
|
expect {
|
234
|
-
|
234
|
+
described_class.parse_spec('2011-07-15', :form)
|
235
235
|
}.to raise_error(ArgumentError)
|
236
236
|
end
|
237
237
|
|
238
|
-
it '
|
239
|
-
expect(
|
240
|
-
expect(
|
238
|
+
it 'parses plain iso dates correctly' do
|
239
|
+
expect(described_class.parse_spec('2011-07-15')).to eq described_class.parse('2011-07-15')
|
240
|
+
expect(described_class.parse_spec('2011/08/05')).to eq described_class.parse('2011-08-05')
|
241
241
|
end
|
242
242
|
|
243
|
-
it "
|
244
|
-
expect(
|
245
|
-
expect(
|
246
|
-
expect(
|
247
|
-
expect(
|
248
|
-
expect(
|
243
|
+
it "parses week numbers such as 'W23' or '23W' correctly" do
|
244
|
+
expect(described_class.parse_spec('W1')).to eq described_class.parse('2012-01-02')
|
245
|
+
expect(described_class.parse_spec('W23')).to eq described_class.parse('2012-06-04')
|
246
|
+
expect(described_class.parse_spec('W23', :to)).to eq described_class.parse('2012-06-10')
|
247
|
+
expect(described_class.parse_spec('23W')).to eq described_class.parse('2012-06-04')
|
248
|
+
expect(described_class.parse_spec('23W', :to)).to eq described_class.parse('2012-06-10')
|
249
249
|
expect {
|
250
|
-
|
250
|
+
described_class.parse_spec('W83', :to)
|
251
251
|
}.to raise_error(ArgumentError)
|
252
252
|
end
|
253
253
|
|
254
|
-
it '
|
255
|
-
expect(
|
256
|
-
expect(
|
257
|
-
expect(
|
258
|
-
expect(
|
259
|
-
expect(
|
260
|
-
expect(
|
254
|
+
it 'parse year-week numbers \'YYYY-W23\' correctly' do
|
255
|
+
expect(described_class.parse_spec('2003-W1')).to eq described_class.parse('2002-12-30')
|
256
|
+
expect(described_class.parse_spec('2003-W1', :to)).to eq described_class.parse('2003-01-05')
|
257
|
+
expect(described_class.parse_spec('2003-W23')).to eq described_class.parse('2003-06-02')
|
258
|
+
expect(described_class.parse_spec('2003-W23', :to)).to eq described_class.parse('2003-06-08')
|
259
|
+
expect(described_class.parse_spec('2003-23W')).to eq described_class.parse('2003-06-02')
|
260
|
+
expect(described_class.parse_spec('2003/23W', :to)).to eq described_class.parse('2003-06-08')
|
261
261
|
expect {
|
262
|
-
|
262
|
+
described_class.parse_spec('2003-W83', :to)
|
263
263
|
}.to raise_error(ArgumentError)
|
264
264
|
end
|
265
265
|
|
266
|
-
it '
|
267
|
-
expect(
|
268
|
-
expect(
|
269
|
-
expect(
|
270
|
-
expect(
|
271
|
-
expect {
|
266
|
+
it 'parses year-half specs such as YYYY-NH or YYYY-HN' do
|
267
|
+
expect(described_class.parse_spec('2011-2H', :from)).to eq described_class.parse('2011-07-01')
|
268
|
+
expect(described_class.parse_spec('2011-2H', :to)).to eq described_class.parse('2011-12-31')
|
269
|
+
expect(described_class.parse_spec('2011-H1', :from)).to eq described_class.parse('2011-01-01')
|
270
|
+
expect(described_class.parse_spec('2011/H1', :to)).to eq described_class.parse('2011-06-30')
|
271
|
+
expect { described_class.parse_spec('2011-3H') }.to raise_error(ArgumentError)
|
272
272
|
end
|
273
273
|
|
274
|
-
it '
|
275
|
-
expect(
|
276
|
-
expect(
|
277
|
-
expect(
|
278
|
-
expect(
|
279
|
-
expect {
|
280
|
-
end
|
281
|
-
|
282
|
-
it '
|
283
|
-
expect(
|
284
|
-
expect(
|
285
|
-
expect(
|
286
|
-
expect(
|
287
|
-
expect {
|
274
|
+
it 'parses half-only specs such as NH or HN' do
|
275
|
+
expect(described_class.parse_spec('2H', :from)).to eq described_class.parse('2012-07-01')
|
276
|
+
expect(described_class.parse_spec('H2', :to)).to eq described_class.parse('2012-12-31')
|
277
|
+
expect(described_class.parse_spec('1H', :from)).to eq described_class.parse('2012-01-01')
|
278
|
+
expect(described_class.parse_spec('H1', :to)).to eq described_class.parse('2012-06-30')
|
279
|
+
expect { described_class.parse_spec('8H') }.to raise_error(ArgumentError)
|
280
|
+
end
|
281
|
+
|
282
|
+
it 'parses year-quarter specs such as YYYY-NQ or YYYY-QN' do
|
283
|
+
expect(described_class.parse_spec('2011-4Q', :from)).to eq described_class.parse('2011-10-01')
|
284
|
+
expect(described_class.parse_spec('2011-4Q', :to)).to eq described_class.parse('2011-12-31')
|
285
|
+
expect(described_class.parse_spec('2011-Q4', :from)).to eq described_class.parse('2011-10-01')
|
286
|
+
expect(described_class.parse_spec('2011/Q4', :to)).to eq described_class.parse('2011-12-31')
|
287
|
+
expect { described_class.parse_spec('2011-5Q') }.to raise_error(ArgumentError)
|
288
288
|
end
|
289
289
|
|
290
|
-
it '
|
291
|
-
expect(
|
292
|
-
expect(
|
293
|
-
expect(
|
294
|
-
expect(
|
295
|
-
expect {
|
290
|
+
it 'parses quarter-only specs such as NQ or QN' do
|
291
|
+
expect(described_class.parse_spec('4Q', :from)).to eq described_class.parse('2012-10-01')
|
292
|
+
expect(described_class.parse_spec('4Q', :to)).to eq described_class.parse('2012-12-31')
|
293
|
+
expect(described_class.parse_spec('Q4', :from)).to eq described_class.parse('2012-10-01')
|
294
|
+
expect(described_class.parse_spec('Q4', :to)).to eq described_class.parse('2012-12-31')
|
295
|
+
expect { described_class.parse_spec('5Q') }.to raise_error(ArgumentError)
|
296
296
|
end
|
297
297
|
|
298
|
-
it '
|
299
|
-
expect(
|
300
|
-
expect(
|
301
|
-
expect {
|
298
|
+
it 'parses year-month specs such as YYYY-MM' do
|
299
|
+
expect(described_class.parse_spec('2010-5', :from)).to eq described_class.parse('2010-05-01')
|
300
|
+
expect(described_class.parse_spec('2010/5', :to)).to eq described_class.parse('2010-05-31')
|
301
|
+
expect { described_class.parse_spec('2010-13') }.to raise_error(ArgumentError)
|
302
302
|
end
|
303
303
|
|
304
|
-
it '
|
305
|
-
expect(
|
306
|
-
expect(
|
307
|
-
expect {
|
308
|
-
expect {
|
304
|
+
it 'parses month-only specs such as MM' do
|
305
|
+
expect(described_class.parse_spec('10', :from)).to eq described_class.parse('2012-10-01')
|
306
|
+
expect(described_class.parse_spec('10', :to)).to eq described_class.parse('2012-10-31')
|
307
|
+
expect { described_class.parse_spec('99') }.to raise_error(ArgumentError)
|
308
|
+
expect { described_class.parse_spec('011') }.to raise_error(ArgumentError)
|
309
309
|
end
|
310
310
|
|
311
|
-
it '
|
312
|
-
expect(
|
313
|
-
expect(
|
314
|
-
expect(
|
315
|
-
expect(
|
316
|
-
expect(
|
317
|
-
expect(
|
318
|
-
expect(
|
319
|
-
expect(
|
320
|
-
expect {
|
321
|
-
expect {
|
322
|
-
expect {
|
323
|
-
expect {
|
311
|
+
it 'parses month-day specs such as MM-DD' do
|
312
|
+
expect(described_class.parse_spec('10-12', :from)).to eq described_class.parse('2012-10-12')
|
313
|
+
expect(described_class.parse_spec('10-2', :from)).to eq described_class.parse('2012-10-02')
|
314
|
+
expect(described_class.parse_spec('5-12', :from)).to eq described_class.parse('2012-05-12')
|
315
|
+
expect(described_class.parse_spec('5-2', :from)).to eq described_class.parse('2012-05-02')
|
316
|
+
expect(described_class.parse_spec('10/12', :from)).to eq described_class.parse('2012-10-12')
|
317
|
+
expect(described_class.parse_spec('10/2', :from)).to eq described_class.parse('2012-10-02')
|
318
|
+
expect(described_class.parse_spec('5/12', :from)).to eq described_class.parse('2012-05-12')
|
319
|
+
expect(described_class.parse_spec('5/2', :from)).to eq described_class.parse('2012-05-02')
|
320
|
+
expect { described_class.parse_spec('99-3') }.to raise_error(ArgumentError)
|
321
|
+
expect { described_class.parse_spec('3-33') }.to raise_error(ArgumentError)
|
322
|
+
expect { described_class.parse_spec('99/3') }.to raise_error(ArgumentError)
|
323
|
+
expect { described_class.parse_spec('3/33') }.to raise_error(ArgumentError)
|
324
324
|
end
|
325
325
|
|
326
|
-
it '
|
327
|
-
expect(
|
328
|
-
expect(
|
329
|
-
expect {
|
326
|
+
it 'parses year-only specs such as YYYY' do
|
327
|
+
expect(described_class.parse_spec('2010', :from)).to eq described_class.parse('2010-01-01')
|
328
|
+
expect(described_class.parse_spec('2010', :to)).to eq described_class.parse('2010-12-31')
|
329
|
+
expect { described_class.parse_spec('99999') }.to raise_error(ArgumentError)
|
330
330
|
end
|
331
331
|
|
332
|
-
it '
|
333
|
-
expect(
|
334
|
-
expect(
|
335
|
-
expect(
|
336
|
-
expect(
|
332
|
+
it 'parses relative day names: today, yesterday' do
|
333
|
+
expect(described_class.parse_spec('today')).to eq described_class.current
|
334
|
+
expect(described_class.parse_spec('this_day')).to eq described_class.current
|
335
|
+
expect(described_class.parse_spec('yesterday')).to eq described_class.current - 1.day
|
336
|
+
expect(described_class.parse_spec('last_day')).to eq described_class.current - 1.day
|
337
337
|
end
|
338
338
|
|
339
|
-
it '
|
340
|
-
expect(
|
341
|
-
expect(
|
342
|
-
expect(
|
343
|
-
expect(
|
339
|
+
it 'parses relative weeks: this_week, last_week' do
|
340
|
+
expect(described_class.parse_spec('this_week')).to eq described_class.parse('2012-07-16')
|
341
|
+
expect(described_class.parse_spec('this_week', :to)).to eq described_class.parse('2012-07-22')
|
342
|
+
expect(described_class.parse_spec('last_week')).to eq described_class.parse('2012-07-09')
|
343
|
+
expect(described_class.parse_spec('last_week', :to)).to eq described_class.parse('2012-07-15')
|
344
344
|
end
|
345
345
|
|
346
|
-
it '
|
347
|
-
expect(
|
348
|
-
expect(
|
349
|
-
.to eq
|
350
|
-
expect(
|
351
|
-
expect(
|
352
|
-
.to eq
|
346
|
+
it 'parses relative biweeks: this_biweek, last_biweek' do
|
347
|
+
expect(described_class.parse_spec('this_biweek')).to eq described_class.parse('2012-07-16')
|
348
|
+
expect(described_class.parse_spec('this_biweek', :to))
|
349
|
+
.to eq described_class.parse('2012-07-29')
|
350
|
+
expect(described_class.parse_spec('last_biweek')).to eq described_class.parse('2012-07-02')
|
351
|
+
expect(described_class.parse_spec('last_biweek', :to))
|
352
|
+
.to eq described_class.parse('2012-07-15')
|
353
353
|
end
|
354
354
|
|
355
|
-
it '
|
356
|
-
expect(
|
357
|
-
expect(
|
358
|
-
.to eq
|
359
|
-
expect(
|
360
|
-
.to eq
|
361
|
-
expect(
|
362
|
-
.to eq
|
355
|
+
it 'parses relative semi-months: this_semimonth, last_semimonth' do
|
356
|
+
expect(described_class.parse_spec('this_semimonth')).to eq described_class.parse('2012-07-16')
|
357
|
+
expect(described_class.parse_spec('this_semimonth', :to))
|
358
|
+
.to eq described_class.parse('2012-07-31')
|
359
|
+
expect(described_class.parse_spec('last_semimonth'))
|
360
|
+
.to eq described_class.parse('2012-07-01')
|
361
|
+
expect(described_class.parse_spec('last_semimonth', :to))
|
362
|
+
.to eq described_class.parse('2012-07-15')
|
363
363
|
end
|
364
364
|
|
365
|
-
it '
|
366
|
-
expect(
|
367
|
-
expect(
|
368
|
-
.to eq
|
369
|
-
expect(
|
370
|
-
expect(
|
371
|
-
.to eq
|
365
|
+
it 'parses relative months: this_month, last_month' do
|
366
|
+
expect(described_class.parse_spec('this_month')).to eq described_class.parse('2012-07-01')
|
367
|
+
expect(described_class.parse_spec('this_month', :to))
|
368
|
+
.to eq described_class.parse('2012-07-31')
|
369
|
+
expect(described_class.parse_spec('last_month')).to eq described_class.parse('2012-06-01')
|
370
|
+
expect(described_class.parse_spec('last_month', :to))
|
371
|
+
.to eq described_class.parse('2012-06-30')
|
372
372
|
end
|
373
|
-
|
374
|
-
it '
|
375
|
-
expect(
|
376
|
-
expect(
|
377
|
-
.to eq
|
378
|
-
expect(
|
379
|
-
.to eq
|
380
|
-
expect(
|
381
|
-
.to eq
|
373
|
+
|
374
|
+
it 'parses relative bimonths: this_bimonth, last_bimonth' do
|
375
|
+
expect(described_class.parse_spec('this_bimonth')).to eq described_class.parse('2012-07-01')
|
376
|
+
expect(described_class.parse_spec('this_bimonth', :to))
|
377
|
+
.to eq described_class.parse('2012-08-31')
|
378
|
+
expect(described_class.parse_spec('last_bimonth'))
|
379
|
+
.to eq described_class.parse('2012-05-01')
|
380
|
+
expect(described_class.parse_spec('last_bimonth', :to))
|
381
|
+
.to eq described_class.parse('2012-06-30')
|
382
382
|
|
383
383
|
# Set today to 2014-12-12: Found that last_bimonth was reporting
|
384
384
|
# current bimonth when today was in the second month of the current
|
385
385
|
# bimonth, i.e., an even month
|
386
|
-
allow(Date).to receive_messages(today:
|
387
|
-
allow(Date).to receive_messages(current:
|
386
|
+
allow(Date).to receive_messages(today: described_class.parse('2014-12-12'))
|
387
|
+
allow(Date).to receive_messages(current: described_class.parse('2014-12-12'))
|
388
388
|
|
389
|
-
expect(
|
390
|
-
.to eq
|
391
|
-
expect(
|
392
|
-
.to eq
|
389
|
+
expect(described_class.parse_spec('last_bimonth'))
|
390
|
+
.to eq described_class.parse('2014-09-01')
|
391
|
+
expect(described_class.parse_spec('last_bimonth', :to))
|
392
|
+
.to eq described_class.parse('2014-10-31')
|
393
393
|
|
394
|
-
allow(Date).to receive_messages(today:
|
395
|
-
allow(Date).to receive_messages(current:
|
394
|
+
allow(Date).to receive_messages(today: described_class.parse('2012-07-18'))
|
395
|
+
allow(Date).to receive_messages(current: described_class.parse('2012-07-18'))
|
396
396
|
end
|
397
397
|
|
398
|
-
it '
|
399
|
-
expect(
|
400
|
-
expect(
|
401
|
-
.to eq
|
402
|
-
expect(
|
403
|
-
.to eq
|
404
|
-
expect(
|
405
|
-
.to eq
|
398
|
+
it 'parses relative quarters: this_quarter, last_quarter' do
|
399
|
+
expect(described_class.parse_spec('this_quarter')).to eq described_class.parse('2012-07-01')
|
400
|
+
expect(described_class.parse_spec('this_quarter', :to))
|
401
|
+
.to eq described_class.parse('2012-09-30')
|
402
|
+
expect(described_class.parse_spec('last_quarter'))
|
403
|
+
.to eq described_class.parse('2012-04-01')
|
404
|
+
expect(described_class.parse_spec('last_quarter', :to))
|
405
|
+
.to eq described_class.parse('2012-06-30')
|
406
406
|
end
|
407
407
|
|
408
408
|
# Today is set to '2012-07-18'
|
409
|
-
it '
|
410
|
-
expect(
|
411
|
-
expect(
|
412
|
-
expect(
|
413
|
-
expect(
|
414
|
-
end
|
415
|
-
|
416
|
-
it '
|
417
|
-
expect(
|
418
|
-
expect(
|
419
|
-
expect(
|
420
|
-
expect(
|
421
|
-
end
|
422
|
-
|
423
|
-
it '
|
424
|
-
expect(
|
425
|
-
expect(
|
426
|
-
expect(
|
427
|
-
end
|
428
|
-
|
429
|
-
it '
|
430
|
-
expect(
|
431
|
-
expect(
|
432
|
-
expect(
|
433
|
-
expect(
|
434
|
-
expect(
|
435
|
-
expect(
|
436
|
-
expect(
|
437
|
-
expect(
|
438
|
-
expect(
|
439
|
-
expect(
|
440
|
-
expect(
|
441
|
-
expect(
|
442
|
-
expect(
|
409
|
+
it 'parses relative halves: this_half, last_half' do
|
410
|
+
expect(described_class.parse_spec('this_half')).to eq described_class.parse('2012-07-01')
|
411
|
+
expect(described_class.parse_spec('this_half', :to)).to eq described_class.parse('2012-12-31')
|
412
|
+
expect(described_class.parse_spec('last_half')).to eq described_class.parse('2012-01-01')
|
413
|
+
expect(described_class.parse_spec('last_half', :to)).to eq described_class.parse('2012-06-30')
|
414
|
+
end
|
415
|
+
|
416
|
+
it 'parses relative years: this_year, last_year' do
|
417
|
+
expect(described_class.parse_spec('this_year')).to eq described_class.parse('2012-01-01')
|
418
|
+
expect(described_class.parse_spec('this_year', :to)).to eq described_class.parse('2012-12-31')
|
419
|
+
expect(described_class.parse_spec('last_year')).to eq described_class.parse('2011-01-01')
|
420
|
+
expect(described_class.parse_spec('last_year', :to)).to eq described_class.parse('2011-12-31')
|
421
|
+
end
|
422
|
+
|
423
|
+
it 'parses forever and never' do
|
424
|
+
expect(described_class.parse_spec('forever')).to eq Date::BOT
|
425
|
+
expect(described_class.parse_spec('forever', :to)).to eq Date::EOT
|
426
|
+
expect(described_class.parse_spec('never')).to be_nil
|
427
|
+
end
|
428
|
+
|
429
|
+
it 'converts a month name into its sequential number' do
|
430
|
+
expect(described_class.mo_name_to_num(' January')).to eq 1
|
431
|
+
expect(described_class.mo_name_to_num(' feb ')).to eq 2
|
432
|
+
expect(described_class.mo_name_to_num(' mAr ')).to eq 3
|
433
|
+
expect(described_class.mo_name_to_num(' Aprol ')).to eq 4
|
434
|
+
expect(described_class.mo_name_to_num("\t \tmaybe")).to eq 5
|
435
|
+
expect(described_class.mo_name_to_num("\t \tjunta\t \t")).to eq 6
|
436
|
+
expect(described_class.mo_name_to_num("\t \tjulia\t \t")).to eq 7
|
437
|
+
expect(described_class.mo_name_to_num("\t \tAugustus\t \t")).to eq 8
|
438
|
+
expect(described_class.mo_name_to_num("September")).to eq 9
|
439
|
+
expect(described_class.mo_name_to_num("octagon")).to eq 10
|
440
|
+
expect(described_class.mo_name_to_num(" novena this month")).to eq 11
|
441
|
+
expect(described_class.mo_name_to_num("decimal")).to eq 12
|
442
|
+
expect(described_class.mo_name_to_num(" dewey decimal")).to be nil
|
443
443
|
end
|
444
444
|
end
|
445
445
|
end
|
446
446
|
|
447
447
|
describe 'instance methods' do
|
448
448
|
describe 'print as string' do
|
449
|
-
it '
|
450
|
-
expect(
|
449
|
+
it 'prints itself as an American-style date' do
|
450
|
+
expect(described_class.parse('2011-02-12').american).to eq('2/12/2011')
|
451
451
|
end
|
452
452
|
|
453
|
-
it '
|
454
|
-
expect(
|
453
|
+
it 'prints itself in iso form' do
|
454
|
+
expect(described_class.today.iso).to eq '2012-07-18'
|
455
455
|
end
|
456
456
|
|
457
|
-
it '
|
458
|
-
expect(
|
457
|
+
it 'prints itself in tex_quote form' do
|
458
|
+
expect(described_class.today.tex_quote).to eq '2012--07--18'
|
459
459
|
end
|
460
460
|
|
461
|
-
it '
|
462
|
-
expect(
|
463
|
-
expect((
|
464
|
-
expect((
|
461
|
+
it 'prints itself in org form' do
|
462
|
+
expect(described_class.today.org).to eq('[2012-07-18 Wed]')
|
463
|
+
expect((described_class.today + 1.day).org).to eq('[2012-07-19 Thu]')
|
464
|
+
expect((described_class.today + 1.day).org(true)).to eq('<2012-07-19 Thu>')
|
465
465
|
end
|
466
466
|
|
467
|
-
it '
|
468
|
-
expect(
|
469
|
-
expect(
|
470
|
-
expect((
|
467
|
+
it 'prints itself in eng form' do
|
468
|
+
expect(described_class.parse('2016-01-05').eng).to eq('January 5, 2016')
|
469
|
+
expect(described_class.today.eng).to eq('July 18, 2012')
|
470
|
+
expect((described_class.today + 1.day).eng).to eq('July 19, 2012')
|
471
471
|
end
|
472
472
|
|
473
|
-
it '
|
474
|
-
expect(
|
475
|
-
expect((
|
473
|
+
it 'prints itself in numeric form' do
|
474
|
+
expect(described_class.today.num).to eq('20120718')
|
475
|
+
expect((described_class.today + 1.day).num).to eq('20120719')
|
476
476
|
end
|
477
477
|
end
|
478
478
|
|
479
479
|
describe 'date arithmetic' do
|
480
|
-
it '
|
481
|
-
expect(
|
480
|
+
it 'knows if its the nth weekday in a given month' do
|
481
|
+
expect(described_class.parse('2014-11-13').nth_wday_in_month?(2, 4, 11))
|
482
482
|
.to be true
|
483
|
-
expect(
|
483
|
+
expect(described_class.parse('2014-11-13').nth_wday_in_month?(-3, 4, 11))
|
484
484
|
.to be true
|
485
|
-
expect(
|
485
|
+
expect(described_class.parse('2014-11-13').nth_wday_in_month?(2, 4, 10))
|
486
486
|
.to be false
|
487
487
|
end
|
488
488
|
|
489
|
-
it '
|
490
|
-
expect(
|
491
|
-
expect(
|
492
|
-
expect(
|
493
|
-
expect(
|
494
|
-
|
495
|
-
expect(
|
496
|
-
expect(
|
497
|
-
end
|
498
|
-
|
499
|
-
it '
|
500
|
-
expect(
|
501
|
-
expect(
|
502
|
-
end
|
503
|
-
|
504
|
-
it '
|
505
|
-
expect(
|
506
|
-
expect(
|
507
|
-
expect(
|
508
|
-
expect(
|
509
|
-
expect(
|
510
|
-
expect(
|
511
|
-
expect(
|
512
|
-
expect(
|
513
|
-
expect(
|
514
|
-
expect(
|
515
|
-
expect(
|
516
|
-
expect(
|
517
|
-
expect(
|
518
|
-
end
|
519
|
-
|
520
|
-
it '
|
521
|
-
expect(
|
522
|
-
expect(
|
523
|
-
expect(
|
524
|
-
expect(
|
525
|
-
end
|
526
|
-
|
527
|
-
it '
|
528
|
-
expect(
|
529
|
-
expect(
|
530
|
-
expect(
|
531
|
-
expect(
|
532
|
-
expect(
|
533
|
-
expect(
|
534
|
-
expect(
|
535
|
-
end
|
536
|
-
|
537
|
-
it '
|
538
|
-
expect(
|
539
|
-
expect(
|
540
|
-
expect(
|
541
|
-
expect(
|
542
|
-
expect(
|
543
|
-
expect(
|
544
|
-
end
|
545
|
-
|
546
|
-
it '
|
547
|
-
expect(
|
548
|
-
.to eq
|
549
|
-
expect(
|
550
|
-
.to eq
|
551
|
-
expect(
|
552
|
-
expect(
|
553
|
-
expect(
|
554
|
-
expect(
|
555
|
-
expect(
|
556
|
-
expect(
|
557
|
-
expect(
|
558
|
-
expect(
|
559
|
-
end
|
560
|
-
|
561
|
-
it '
|
562
|
-
expect(
|
563
|
-
expect(
|
564
|
-
expect(
|
565
|
-
expect(
|
566
|
-
expect(
|
567
|
-
expect(
|
568
|
-
end
|
569
|
-
|
570
|
-
it '
|
571
|
-
expect(
|
572
|
-
.to eq
|
573
|
-
expect(
|
574
|
-
.to eq
|
575
|
-
expect(
|
576
|
-
.to eq
|
577
|
-
expect(
|
578
|
-
.to eq
|
579
|
-
expect(
|
489
|
+
it 'knows if its a weekend or a weekday' do
|
490
|
+
expect(described_class.parse('2014-05-17')).to be_weekend
|
491
|
+
expect(described_class.parse('2014-05-17')).not_to be_weekday
|
492
|
+
expect(described_class.parse('2014-05-18')).to be_weekend
|
493
|
+
expect(described_class.parse('2014-05-18')).not_to be_weekday
|
494
|
+
|
495
|
+
expect(described_class.parse('2014-05-22')).to be_weekday
|
496
|
+
expect(described_class.parse('2014-05-22')).not_to be_weekend
|
497
|
+
end
|
498
|
+
|
499
|
+
it 'knows its pred and succ (for Range)' do
|
500
|
+
expect(described_class.today.pred).to eq(described_class.today - 1)
|
501
|
+
expect(described_class.today.succ).to eq(described_class.today + 1)
|
502
|
+
end
|
503
|
+
|
504
|
+
it 'knows its quarter' do
|
505
|
+
expect(described_class.today.quarter).to eq(3)
|
506
|
+
expect(described_class.parse('2012-02-29').quarter).to eq(1)
|
507
|
+
expect(described_class.parse('2012-01-01').quarter).to eq(1)
|
508
|
+
expect(described_class.parse('2012-03-31').quarter).to eq(1)
|
509
|
+
expect(described_class.parse('2012-04-01').quarter).to eq(2)
|
510
|
+
expect(described_class.parse('2012-05-15').quarter).to eq(2)
|
511
|
+
expect(described_class.parse('2012-06-30').quarter).to eq(2)
|
512
|
+
expect(described_class.parse('2012-07-01').quarter).to eq(3)
|
513
|
+
expect(described_class.parse('2012-08-15').quarter).to eq(3)
|
514
|
+
expect(described_class.parse('2012-09-30').quarter).to eq(3)
|
515
|
+
expect(described_class.parse('2012-10-01').quarter).to eq(4)
|
516
|
+
expect(described_class.parse('2012-11-15').quarter).to eq(4)
|
517
|
+
expect(described_class.parse('2012-12-31').quarter).to eq(4)
|
518
|
+
end
|
519
|
+
|
520
|
+
it 'knows about years' do
|
521
|
+
expect(described_class.parse('2013-01-01')).to be_beginning_of_year
|
522
|
+
expect(described_class.parse('2013-12-31')).to be_end_of_year
|
523
|
+
expect(described_class.parse('2013-04-01')).not_to be_beginning_of_year
|
524
|
+
expect(described_class.parse('2013-12-30')).not_to be_end_of_year
|
525
|
+
end
|
526
|
+
|
527
|
+
it 'knows about halves' do
|
528
|
+
expect(described_class.parse('2013-01-01')).to be_beginning_of_half
|
529
|
+
expect(described_class.parse('2013-12-31')).to be_end_of_half
|
530
|
+
expect(described_class.parse('2013-07-01')).to be_beginning_of_half
|
531
|
+
expect(described_class.parse('2013-06-30')).to be_end_of_half
|
532
|
+
expect(described_class.parse('2013-05-01')).not_to be_beginning_of_half
|
533
|
+
expect(described_class.parse('2013-05-01').half).to eq(1)
|
534
|
+
expect(described_class.parse('2013-07-31').half).to eq(2)
|
535
|
+
end
|
536
|
+
|
537
|
+
it 'knows about quarters' do
|
538
|
+
expect(described_class.parse('2013-01-01')).to be_beginning_of_quarter
|
539
|
+
expect(described_class.parse('2013-12-31')).to be_end_of_quarter
|
540
|
+
expect(described_class.parse('2013-04-01')).to be_beginning_of_quarter
|
541
|
+
expect(described_class.parse('2013-06-30')).to be_end_of_quarter
|
542
|
+
expect(described_class.parse('2013-05-01')).not_to be_beginning_of_quarter
|
543
|
+
expect(described_class.parse('2013-07-31')).not_to be_end_of_quarter
|
544
|
+
end
|
545
|
+
|
546
|
+
it 'knows about bimonths' do
|
547
|
+
expect(described_class.parse('2013-11-04').beginning_of_bimonth)
|
548
|
+
.to eq described_class.parse('2013-11-01')
|
549
|
+
expect(described_class.parse('2013-11-04').end_of_bimonth)
|
550
|
+
.to eq described_class.parse('2013-12-31')
|
551
|
+
expect(described_class.parse('2013-03-01')).to be_beginning_of_bimonth
|
552
|
+
expect(described_class.parse('2013-04-30')).to be_end_of_bimonth
|
553
|
+
expect(described_class.parse('2013-01-01')).to be_beginning_of_bimonth
|
554
|
+
expect(described_class.parse('2013-12-31')).to be_end_of_bimonth
|
555
|
+
expect(described_class.parse('2013-05-01')).to be_beginning_of_bimonth
|
556
|
+
expect(described_class.parse('2013-06-30')).to be_end_of_bimonth
|
557
|
+
expect(described_class.parse('2013-06-01')).not_to be_beginning_of_bimonth
|
558
|
+
expect(described_class.parse('2013-07-31')).not_to be_end_of_bimonth
|
559
|
+
end
|
560
|
+
|
561
|
+
it 'knows about months' do
|
562
|
+
expect(described_class.parse('2013-01-01')).to be_beginning_of_month
|
563
|
+
expect(described_class.parse('2013-12-31')).to be_end_of_month
|
564
|
+
expect(described_class.parse('2013-05-01')).to be_beginning_of_month
|
565
|
+
expect(described_class.parse('2013-07-31')).to be_end_of_month
|
566
|
+
expect(described_class.parse('2013-05-02')).not_to be_beginning_of_month
|
567
|
+
expect(described_class.parse('2013-07-30')).not_to be_end_of_month
|
568
|
+
end
|
569
|
+
|
570
|
+
it 'knows about semimonths' do
|
571
|
+
expect(described_class.parse('2013-11-24').beginning_of_semimonth)
|
572
|
+
.to eq described_class.parse('2013-11-16')
|
573
|
+
expect(described_class.parse('2013-11-04').beginning_of_semimonth)
|
574
|
+
.to eq described_class.parse('2013-11-01')
|
575
|
+
expect(described_class.parse('2013-11-04').end_of_semimonth)
|
576
|
+
.to eq described_class.parse('2013-11-15')
|
577
|
+
expect(described_class.parse('2013-11-24').end_of_semimonth)
|
578
|
+
.to eq described_class.parse('2013-11-30')
|
579
|
+
expect(described_class.parse('2013-03-01'))
|
580
580
|
.to be_beginning_of_semimonth
|
581
|
-
expect(
|
581
|
+
expect(described_class.parse('2013-03-16'))
|
582
582
|
.to be_beginning_of_semimonth
|
583
|
-
expect(
|
583
|
+
expect(described_class.parse('2013-04-15'))
|
584
584
|
.to be_end_of_semimonth
|
585
|
-
expect(
|
585
|
+
expect(described_class.parse('2013-04-30'))
|
586
586
|
.to be_end_of_semimonth
|
587
587
|
end
|
588
588
|
|
589
589
|
it 'knows about biweeks' do
|
590
|
-
expect(
|
591
|
-
.to eq
|
592
|
-
expect(
|
593
|
-
.to eq
|
594
|
-
expect(
|
595
|
-
expect(
|
596
|
-
expect(
|
597
|
-
.to eq
|
598
|
-
expect(
|
599
|
-
.to eq
|
590
|
+
expect(described_class.parse('2013-11-07').beginning_of_biweek)
|
591
|
+
.to eq described_class.parse('2013-11-04')
|
592
|
+
expect(described_class.parse('2013-11-07').end_of_biweek)
|
593
|
+
.to eq described_class.parse('2013-11-17')
|
594
|
+
expect(described_class.parse('2013-03-11')).to be_beginning_of_biweek
|
595
|
+
expect(described_class.parse('2013-03-24')).to be_end_of_biweek
|
596
|
+
expect(described_class.parse('2013-12-30').end_of_biweek)
|
597
|
+
.to eq described_class.parse('2014-01-12')
|
598
|
+
expect(described_class.parse('2009-12-30').end_of_biweek)
|
599
|
+
.to eq described_class.parse('2010-01-03')
|
600
600
|
end
|
601
601
|
|
602
602
|
it 'knows that a Monday is the beginning of the week' do
|
603
603
|
# A Monday
|
604
|
-
expect(
|
605
|
-
expect(
|
604
|
+
expect(described_class.parse('2013-11-04')).to be_beginning_of_week
|
605
|
+
expect(described_class.parse('2013-12-02')).to be_beginning_of_week
|
606
606
|
# A Sunday
|
607
|
-
expect(
|
607
|
+
expect(described_class.parse('2013-10-13')).not_to be_beginning_of_week
|
608
608
|
end
|
609
609
|
|
610
610
|
it 'knows that a Sunday is the end of the week' do
|
611
611
|
# A Sunday
|
612
|
-
expect(
|
613
|
-
expect(
|
612
|
+
expect(described_class.parse('2013-11-10')).to be_end_of_week
|
613
|
+
expect(described_class.parse('2013-12-08')).to be_end_of_week
|
614
614
|
# A Saturday
|
615
|
-
expect(
|
616
|
-
end
|
617
|
-
|
618
|
-
it '
|
619
|
-
expect(
|
620
|
-
.to eq
|
621
|
-
expect(
|
622
|
-
.to eq
|
623
|
-
expect(
|
624
|
-
.to eq
|
625
|
-
expect(
|
626
|
-
.to eq
|
627
|
-
expect(
|
628
|
-
.to eq
|
629
|
-
expect(
|
630
|
-
.to eq
|
631
|
-
expect(
|
632
|
-
.to eq
|
615
|
+
expect(described_class.parse('2013-10-19')).not_to be_end_of_week
|
616
|
+
end
|
617
|
+
|
618
|
+
it 'knows the beginning of non-week chunks' do
|
619
|
+
expect(described_class.parse('2013-11-04').beginning_of_chunk(:year))
|
620
|
+
.to eq described_class.parse('2013-01-01')
|
621
|
+
expect(described_class.parse('2013-11-04').beginning_of_chunk(:half))
|
622
|
+
.to eq described_class.parse('2013-07-01')
|
623
|
+
expect(described_class.parse('2013-11-04').beginning_of_chunk(:quarter))
|
624
|
+
.to eq described_class.parse('2013-10-01')
|
625
|
+
expect(described_class.parse('2013-12-04').beginning_of_chunk(:bimonth))
|
626
|
+
.to eq described_class.parse('2013-11-01')
|
627
|
+
expect(described_class.parse('2013-11-04').beginning_of_chunk(:month))
|
628
|
+
.to eq described_class.parse('2013-11-01')
|
629
|
+
expect(described_class.parse('2013-11-04').beginning_of_chunk(:semimonth))
|
630
|
+
.to eq described_class.parse('2013-11-01')
|
631
|
+
expect(described_class.parse('2013-11-24').beginning_of_chunk(:semimonth))
|
632
|
+
.to eq described_class.parse('2013-11-16')
|
633
633
|
end
|
634
634
|
|
635
635
|
it 'knows the beginning and end of bi-week-based chunks' do
|
636
636
|
# First Friday to prior Monday
|
637
|
-
expect(
|
638
|
-
.to eq
|
637
|
+
expect(described_class.parse('2013-11-08').beginning_of_chunk(:biweek))
|
638
|
+
.to eq described_class.parse('2013-11-04')
|
639
639
|
# Second Wednesday to 2 prior Monday
|
640
|
-
expect(
|
641
|
-
.to eq
|
640
|
+
expect(described_class.parse('2013-11-13').beginning_of_chunk(:biweek))
|
641
|
+
.to eq described_class.parse('2013-11-04')
|
642
642
|
end
|
643
643
|
|
644
644
|
it 'knows the beginning and end of week-based chunks' do
|
645
645
|
# A Friday to prior Monday
|
646
|
-
expect(
|
647
|
-
.to eq
|
646
|
+
expect(described_class.parse('2013-11-08').beginning_of_chunk(:week))
|
647
|
+
.to eq described_class.parse('2013-11-04')
|
648
648
|
# A Friday to following Sunday
|
649
|
-
expect(
|
650
|
-
.to eq
|
649
|
+
expect(described_class.parse('2013-11-08').end_of_chunk(:week))
|
650
|
+
.to eq described_class.parse('2013-11-10')
|
651
651
|
# A Sunday to prior Monday
|
652
|
-
expect(
|
653
|
-
.to eq
|
652
|
+
expect(described_class.parse('2013-11-10').beginning_of_chunk(:week))
|
653
|
+
.to eq described_class.parse('2013-11-04')
|
654
654
|
# A Sunday to itself
|
655
|
-
expect(
|
656
|
-
.to eq
|
655
|
+
expect(described_class.parse('2013-11-10').end_of_chunk(:week))
|
656
|
+
.to eq described_class.parse('2013-11-10')
|
657
657
|
expect {
|
658
|
-
|
658
|
+
described_class.parse('2013-11-04').beginning_of_chunk(:wek)
|
659
659
|
}.to raise_error(ArgumentError)
|
660
660
|
end
|
661
661
|
|
662
|
-
it '
|
663
|
-
expect(
|
662
|
+
it 'tests the beginning of chunks' do
|
663
|
+
expect(described_class.parse('2013-11-04').beginning_of_chunk?(:year))
|
664
664
|
.to be false
|
665
|
-
expect(
|
665
|
+
expect(described_class.parse('2013-01-01').beginning_of_chunk?(:year))
|
666
666
|
.to be true
|
667
|
-
expect(
|
667
|
+
expect(described_class.parse('2013-11-04').beginning_of_chunk?(:half))
|
668
668
|
.to be false
|
669
|
-
expect(
|
669
|
+
expect(described_class.parse('2013-01-01').beginning_of_chunk?(:half))
|
670
670
|
.to be true
|
671
|
-
expect(
|
671
|
+
expect(described_class.parse('2013-07-01').beginning_of_chunk?(:half))
|
672
672
|
.to be true
|
673
|
-
expect(
|
673
|
+
expect(described_class.parse('2013-11-04').beginning_of_chunk?(:quarter))
|
674
674
|
.to be false
|
675
|
-
expect(
|
675
|
+
expect(described_class.parse('2013-01-01').beginning_of_chunk?(:quarter))
|
676
676
|
.to be true
|
677
|
-
expect(
|
677
|
+
expect(described_class.parse('2013-07-01').beginning_of_chunk?(:quarter))
|
678
678
|
.to be true
|
679
|
-
expect(
|
679
|
+
expect(described_class.parse('2013-10-01').beginning_of_chunk?(:quarter))
|
680
680
|
.to be true
|
681
|
-
expect(
|
681
|
+
expect(described_class.parse('2013-11-04').beginning_of_chunk?(:bimonth))
|
682
682
|
.to be false
|
683
|
-
expect(
|
683
|
+
expect(described_class.parse('2013-01-01').beginning_of_chunk?(:bimonth))
|
684
684
|
.to be true
|
685
|
-
expect(
|
685
|
+
expect(described_class.parse('2013-02-01').beginning_of_chunk?(:bimonth))
|
686
686
|
.to be false
|
687
|
-
expect(
|
687
|
+
expect(described_class.parse('2013-11-04').beginning_of_chunk?(:month))
|
688
688
|
.to be false
|
689
|
-
expect(
|
689
|
+
expect(described_class.parse('2013-01-01').beginning_of_chunk?(:month))
|
690
690
|
.to be true
|
691
|
-
expect(
|
691
|
+
expect(described_class.parse('2013-11-04').beginning_of_chunk?(:semimonth))
|
692
692
|
.to be false
|
693
|
-
expect(
|
693
|
+
expect(described_class.parse('2013-01-01').beginning_of_chunk?(:semimonth))
|
694
694
|
.to be true
|
695
|
-
expect(
|
695
|
+
expect(described_class.parse('2013-01-16').beginning_of_chunk?(:semimonth))
|
696
696
|
.to be true
|
697
|
-
expect(
|
697
|
+
expect(described_class.parse('2013-11-01').beginning_of_chunk?(:week))
|
698
698
|
.to be false
|
699
|
-
expect(
|
699
|
+
expect(described_class.parse('2013-11-04').beginning_of_chunk?(:week))
|
700
700
|
.to be true
|
701
701
|
# Sunday is not beginning of commercial week
|
702
|
-
expect(
|
702
|
+
expect(described_class.parse('2013-11-03').beginning_of_chunk?(:week))
|
703
703
|
.to be false
|
704
|
-
expect(
|
704
|
+
expect(described_class.parse('2013-11-01').beginning_of_chunk?(:day))
|
705
705
|
.to be true
|
706
|
-
expect(
|
706
|
+
expect(described_class.parse('2013-11-04').beginning_of_chunk?(:day))
|
707
707
|
.to be true
|
708
|
-
expect(
|
708
|
+
expect(described_class.parse('2013-11-03').beginning_of_chunk?(:day))
|
709
709
|
.to be true
|
710
710
|
|
711
711
|
expect {
|
712
|
-
|
712
|
+
described_class.parse('2013-11-04').beginning_of_chunk?(:wek)
|
713
713
|
}.to raise_error(ArgumentError)
|
714
714
|
end
|
715
715
|
|
716
|
-
it '
|
717
|
-
expect(
|
716
|
+
it 'tests the end of chunks' do
|
717
|
+
expect(described_class.parse('2013-11-04').end_of_chunk?(:year))
|
718
718
|
.to be false
|
719
|
-
expect(
|
719
|
+
expect(described_class.parse('2013-12-31').end_of_chunk?(:year))
|
720
720
|
.to be true
|
721
|
-
expect(
|
721
|
+
expect(described_class.parse('2013-11-04').end_of_chunk?(:half))
|
722
722
|
.to be false
|
723
|
-
expect(
|
723
|
+
expect(described_class.parse('2013-12-31').end_of_chunk?(:half))
|
724
724
|
.to be true
|
725
|
-
expect(
|
725
|
+
expect(described_class.parse('2013-06-30').end_of_chunk?(:half))
|
726
726
|
.to be true
|
727
|
-
expect(
|
727
|
+
expect(described_class.parse('2013-11-04').end_of_chunk?(:quarter))
|
728
728
|
.to be false
|
729
|
-
expect(
|
729
|
+
expect(described_class.parse('2013-12-31').end_of_chunk?(:quarter))
|
730
730
|
.to be true
|
731
|
-
expect(
|
731
|
+
expect(described_class.parse('2013-06-30').end_of_chunk?(:quarter))
|
732
732
|
.to be true
|
733
|
-
expect(
|
733
|
+
expect(described_class.parse('2013-09-30').end_of_chunk?(:quarter))
|
734
734
|
.to be true
|
735
|
-
expect(
|
735
|
+
expect(described_class.parse('2013-11-04').end_of_chunk?(:bimonth))
|
736
736
|
.to be false
|
737
|
-
expect(
|
737
|
+
expect(described_class.parse('2013-12-31').end_of_chunk?(:bimonth))
|
738
738
|
.to be true
|
739
|
-
expect(
|
739
|
+
expect(described_class.parse('2013-02-01').end_of_chunk?(:bimonth))
|
740
740
|
.to be false
|
741
|
-
expect(
|
741
|
+
expect(described_class.parse('2013-11-04').end_of_chunk?(:month))
|
742
742
|
.to be false
|
743
|
-
expect(
|
743
|
+
expect(described_class.parse('2013-12-31').end_of_chunk?(:month))
|
744
744
|
.to be true
|
745
|
-
expect(
|
745
|
+
expect(described_class.parse('2013-11-04').end_of_chunk?(:semimonth))
|
746
746
|
.to be false
|
747
|
-
expect(
|
747
|
+
expect(described_class.parse('2013-12-31').end_of_chunk?(:semimonth))
|
748
748
|
.to be true
|
749
|
-
expect(
|
749
|
+
expect(described_class.parse('2013-01-15').end_of_chunk?(:semimonth))
|
750
750
|
.to be true
|
751
|
-
expect(
|
751
|
+
expect(described_class.parse('2013-11-01').end_of_chunk?(:week))
|
752
752
|
.to be false
|
753
|
-
expect(
|
753
|
+
expect(described_class.parse('2013-11-04').end_of_chunk?(:week))
|
754
754
|
.to be false
|
755
755
|
# Sunday is not end of commercial week
|
756
|
-
expect(
|
756
|
+
expect(described_class.parse('2013-11-03').end_of_chunk?(:week))
|
757
757
|
.to be true
|
758
|
-
expect(
|
758
|
+
expect(described_class.parse('2013-11-01').end_of_chunk?(:day))
|
759
759
|
.to be true
|
760
|
-
expect(
|
760
|
+
expect(described_class.parse('2013-11-04').end_of_chunk?(:day))
|
761
761
|
.to be true
|
762
|
-
expect(
|
762
|
+
expect(described_class.parse('2013-11-03').end_of_chunk?(:day))
|
763
763
|
.to be true
|
764
764
|
|
765
765
|
expect {
|
766
|
-
|
766
|
+
described_class.parse('2013-11-04').end_of_chunk?(:wek)
|
767
767
|
}.to raise_error(ArgumentError)
|
768
768
|
end
|
769
769
|
|
770
|
-
it '
|
771
|
-
#
|
772
|
-
expect(
|
773
|
-
expect(
|
774
|
-
expect(
|
775
|
-
expect(
|
776
|
-
expect(
|
777
|
-
expect(
|
778
|
-
expect(
|
779
|
-
expect(
|
780
|
-
expect(
|
770
|
+
it 'adds a chunk sym to itself' do
|
771
|
+
# described_class.today is '2012-07-18'
|
772
|
+
expect(described_class.today.add_chunk(:year)).to eq(described_class.parse('2013-07-18'))
|
773
|
+
expect(described_class.today.add_chunk(:half)).to eq(described_class.parse('2013-01-18'))
|
774
|
+
expect(described_class.today.add_chunk(:quarter)).to eq(described_class.parse('2012-10-18'))
|
775
|
+
expect(described_class.today.add_chunk(:bimonth)).to eq(described_class.parse('2012-09-18'))
|
776
|
+
expect(described_class.today.add_chunk(:month)).to eq(described_class.parse('2012-08-18'))
|
777
|
+
expect(described_class.today.add_chunk(:semimonth)).to eq(described_class.parse('2012-08-03'))
|
778
|
+
expect(described_class.today.add_chunk(:biweek)).to eq(described_class.parse('2012-08-01'))
|
779
|
+
expect(described_class.today.add_chunk(:week)).to eq(described_class.parse('2012-07-25'))
|
780
|
+
expect(described_class.today.add_chunk(:day)).to eq(described_class.parse('2012-07-19'))
|
781
781
|
expect {
|
782
|
-
|
782
|
+
described_class.today.add_chunk(:hour)
|
783
783
|
}.to raise_error(ArgumentError)
|
784
784
|
end
|
785
785
|
|
786
|
-
it '
|
787
|
-
#
|
788
|
-
expect(
|
789
|
-
expect(
|
790
|
-
expect(
|
791
|
-
expect(
|
792
|
-
expect(
|
793
|
-
expect(
|
794
|
-
expect(
|
795
|
-
expect(
|
796
|
-
expect(
|
786
|
+
it 'adds n chunks to itself' do
|
787
|
+
# described_class.today is '2012-07-18'
|
788
|
+
expect(described_class.today.add_chunk(:year, 5)).to eq(described_class.parse('2017-07-18'))
|
789
|
+
expect(described_class.today.add_chunk(:half, 5)).to eq(described_class.parse('2015-01-18'))
|
790
|
+
expect(described_class.today.add_chunk(:quarter, 5)).to eq(described_class.parse('2013-10-18'))
|
791
|
+
expect(described_class.today.add_chunk(:bimonth, 5)).to eq(described_class.parse('2013-05-18'))
|
792
|
+
expect(described_class.today.add_chunk(:month, 5)).to eq(described_class.parse('2012-12-18'))
|
793
|
+
expect(described_class.today.add_chunk(:semimonth, 5)).to eq(described_class.parse('2012-10-03'))
|
794
|
+
expect(described_class.today.add_chunk(:biweek, 5)).to eq(described_class.parse('2012-09-26'))
|
795
|
+
expect(described_class.today.add_chunk(:week, 5)).to eq(described_class.parse('2012-08-22'))
|
796
|
+
expect(described_class.today.add_chunk(:day, 5)).to eq(described_class.parse('2012-07-23'))
|
797
797
|
expect {
|
798
|
-
|
798
|
+
described_class.today.add_chunk(:hour)
|
799
799
|
}.to raise_error(ArgumentError)
|
800
800
|
end
|
801
801
|
|
802
|
-
it '
|
803
|
-
expect(
|
804
|
-
.to eq
|
805
|
-
expect(
|
806
|
-
.to eq
|
807
|
-
expect(
|
808
|
-
.to eq
|
809
|
-
expect(
|
810
|
-
.to eq
|
811
|
-
expect(
|
812
|
-
.to eq
|
813
|
-
expect(
|
814
|
-
.to eq
|
815
|
-
expect(
|
816
|
-
.to eq
|
817
|
-
expect(
|
818
|
-
.to eq
|
819
|
-
expect(
|
820
|
-
.to eq
|
802
|
+
it 'knows the end of chunks' do
|
803
|
+
expect(described_class.parse('2013-07-04').end_of_chunk(:year))
|
804
|
+
.to eq described_class.parse('2013-12-31')
|
805
|
+
expect(described_class.parse('2013-05-04').end_of_chunk(:half))
|
806
|
+
.to eq described_class.parse('2013-06-30')
|
807
|
+
expect(described_class.parse('2013-07-04').end_of_chunk(:quarter))
|
808
|
+
.to eq described_class.parse('2013-09-30')
|
809
|
+
expect(described_class.parse('2013-12-04').end_of_chunk(:bimonth))
|
810
|
+
.to eq described_class.parse('2013-12-31')
|
811
|
+
expect(described_class.parse('2013-07-04').end_of_chunk(:month))
|
812
|
+
.to eq described_class.parse('2013-07-31')
|
813
|
+
expect(described_class.parse('2013-11-04').end_of_chunk(:semimonth))
|
814
|
+
.to eq described_class.parse('2013-11-15')
|
815
|
+
expect(described_class.parse('2013-11-24').end_of_chunk(:semimonth))
|
816
|
+
.to eq described_class.parse('2013-11-30')
|
817
|
+
expect(described_class.parse('2013-11-08').end_of_chunk(:biweek))
|
818
|
+
.to eq described_class.parse('2013-11-17')
|
819
|
+
expect(described_class.parse('2013-07-04').end_of_chunk(:week))
|
820
|
+
.to eq described_class.parse('2013-07-07')
|
821
821
|
expect {
|
822
|
-
|
822
|
+
described_class.parse('2013-11-04').end_of_chunk(:wek)
|
823
823
|
}.to raise_error(ArgumentError)
|
824
824
|
end
|
825
825
|
|
826
|
-
it "
|
826
|
+
it "knows if it's within 6 months of another date" do
|
827
827
|
# This uses Section 16's logic that one date is "within a
|
828
828
|
# period of less than six months" of another date only if it
|
829
829
|
# is within the date six months minus 2 days away from the
|
830
|
-
# current
|
831
|
-
expect(
|
832
|
-
.to be_within_6mos_of(
|
833
|
-
expect(
|
834
|
-
.not_to be_within_6mos_of(
|
835
|
-
expect(
|
836
|
-
.not_to be_within_6mos_of(
|
837
|
-
expect(
|
838
|
-
.to be_within_6mos_of(
|
830
|
+
# current described_class.
|
831
|
+
expect(described_class.parse('2014-01-12'))
|
832
|
+
.to be_within_6mos_of(described_class.parse('2014-06-12'))
|
833
|
+
expect(described_class.parse('2014-01-12'))
|
834
|
+
.not_to be_within_6mos_of(described_class.parse('2014-07-12'))
|
835
|
+
expect(described_class.parse('2014-01-12'))
|
836
|
+
.not_to be_within_6mos_of(described_class.parse('2014-07-11'))
|
837
|
+
expect(described_class.parse('2014-01-12'))
|
838
|
+
.to be_within_6mos_of(described_class.parse('2014-07-10'))
|
839
|
+
end
|
840
|
+
|
841
|
+
it "knows if it's within 6 months of another date if it's near end of month" do
|
842
|
+
# This tests for the Jammies Interntional twist where there is no
|
843
|
+
# corresponding day in the sixth month before or after the given described_class.
|
844
|
+
|
845
|
+
# Looking backward to Feb
|
846
|
+
expect(described_class.parse('2014-02-28'))
|
847
|
+
.not_to be_within_6mos_of(described_class.parse('2014-08-31'))
|
848
|
+
expect(described_class.parse('2014-03-01'))
|
849
|
+
.not_to be_within_6mos_of(described_class.parse('2014-08-31'))
|
850
|
+
expect(described_class.parse('2014-03-02'))
|
851
|
+
.to be_within_6mos_of(described_class.parse('2014-08-31'))
|
852
|
+
# Looking forward to Feb
|
853
|
+
expect(described_class.parse('2015-02-28'))
|
854
|
+
.not_to be_within_6mos_of(described_class.parse('2014-08-31'))
|
855
|
+
expect(described_class.parse('2015-02-27'))
|
856
|
+
.not_to be_within_6mos_of(described_class.parse('2014-08-31'))
|
857
|
+
expect(described_class.parse('2015-02-26'))
|
858
|
+
.to be_within_6mos_of(described_class.parse('2014-08-31'))
|
859
|
+
# Same in a leap year, backward
|
860
|
+
expect(described_class.parse('2012-02-29'))
|
861
|
+
.not_to be_within_6mos_of(described_class.parse('2012-08-31'))
|
862
|
+
expect(described_class.parse('2012-03-01'))
|
863
|
+
.not_to be_within_6mos_of(described_class.parse('2012-08-31'))
|
864
|
+
expect(described_class.parse('2012-03-02'))
|
865
|
+
.to be_within_6mos_of(described_class.parse('2012-08-31'))
|
866
|
+
# Same in a leap year, forward
|
867
|
+
expect(described_class.parse('2012-02-29'))
|
868
|
+
.not_to be_within_6mos_of(described_class.parse('2011-08-31'))
|
869
|
+
expect(described_class.parse('2012-02-28'))
|
870
|
+
.not_to be_within_6mos_of(described_class.parse('2011-08-31'))
|
871
|
+
expect(described_class.parse('2012-02-27'))
|
872
|
+
.to be_within_6mos_of(described_class.parse('2011-08-31'))
|
873
|
+
|
874
|
+
# Now try from October to April, as 31->30 test.
|
875
|
+
expect(described_class.parse('2012-04-30'))
|
876
|
+
.not_to be_within_6mos_of(described_class.parse('2012-10-31'))
|
877
|
+
expect(described_class.parse('2012-05-01'))
|
878
|
+
.not_to be_within_6mos_of(described_class.parse('2012-10-31'))
|
879
|
+
expect(described_class.parse('2012-05-02'))
|
880
|
+
.to be_within_6mos_of(described_class.parse('2012-10-31'))
|
881
|
+
# And forward
|
882
|
+
expect(described_class.parse('2013-04-30'))
|
883
|
+
.not_to be_within_6mos_of(described_class.parse('2012-10-31'))
|
884
|
+
expect(described_class.parse('2013-04-29'))
|
885
|
+
.not_to be_within_6mos_of(described_class.parse('2012-10-31'))
|
886
|
+
expect(described_class.parse('2013-04-28'))
|
887
|
+
.to be_within_6mos_of(described_class.parse('2012-10-31'))
|
888
|
+
|
889
|
+
# It's not symmetrical: notice the second example here is within six
|
890
|
+
# months if measured from April, but not if measured from October.
|
891
|
+
expect(described_class.parse('2012-10-31'))
|
892
|
+
.not_to be_within_6mos_of(described_class.parse('2013-04-30'))
|
893
|
+
expect(described_class.parse('2012-10-31'))
|
894
|
+
.to be_within_6mos_of(described_class.parse('2013-04-29'))
|
895
|
+
expect(described_class.parse('2012-10-31'))
|
896
|
+
.to be_within_6mos_of(described_class.parse('2013-04-28'))
|
839
897
|
end
|
840
898
|
end
|
841
899
|
|
842
900
|
describe 'holidays' do
|
843
|
-
it '
|
844
|
-
expect(
|
845
|
-
expect(
|
846
|
-
expect(
|
901
|
+
it 'knows Easter in its year' do
|
902
|
+
expect(described_class.today.easter_this_year).to eq(described_class.parse('2012-04-08'))
|
903
|
+
expect(described_class.parse('2014-04-20').easter?).to be true
|
904
|
+
expect(described_class.parse('2014-03-20').easter?).to be false
|
847
905
|
end
|
848
906
|
|
849
|
-
it '
|
907
|
+
it 'knows if its a federal holiday' do
|
850
908
|
# Got these from:
|
851
909
|
# http://www.opm.gov/policy-data-oversight/snow-dismissal-procedures/federal-holidays/
|
852
910
|
|
@@ -861,16 +919,16 @@ describe Date do
|
|
861
919
|
# Friday, November 11 Veterans Day
|
862
920
|
# Thursday, November 24 Thanksgiving Day
|
863
921
|
# Tuesday, December 26 *** Christmas Day
|
864
|
-
expect(
|
865
|
-
expect(
|
866
|
-
expect(
|
867
|
-
expect(
|
868
|
-
expect(
|
869
|
-
expect(
|
870
|
-
expect(
|
871
|
-
expect(
|
872
|
-
expect(
|
873
|
-
expect(
|
922
|
+
expect(described_class.parse('2010-12-31')).to be_fed_holiday
|
923
|
+
expect(described_class.parse('2011-01-17')).to be_fed_holiday
|
924
|
+
expect(described_class.parse('2011-02-21')).to be_fed_holiday
|
925
|
+
expect(described_class.parse('2011-05-30')).to be_fed_holiday
|
926
|
+
expect(described_class.parse('2011-07-04')).to be_fed_holiday
|
927
|
+
expect(described_class.parse('2011-09-05')).to be_fed_holiday
|
928
|
+
expect(described_class.parse('2011-10-10')).to be_fed_holiday
|
929
|
+
expect(described_class.parse('2011-11-11')).to be_fed_holiday
|
930
|
+
expect(described_class.parse('2011-11-24')).to be_fed_holiday
|
931
|
+
expect(described_class.parse('2011-12-26')).to be_fed_holiday
|
874
932
|
|
875
933
|
# For 2014:
|
876
934
|
# Wednesday, January 1 New Year's Day
|
@@ -883,19 +941,19 @@ describe Date do
|
|
883
941
|
# Tuesday, November 11 Veterans Day
|
884
942
|
# Thursday, November 27 Thanksgiving Day
|
885
943
|
# Thursday, December 25 Christmas Day
|
886
|
-
expect(
|
887
|
-
expect(
|
888
|
-
expect(
|
889
|
-
expect(
|
890
|
-
expect(
|
891
|
-
expect(
|
892
|
-
expect(
|
893
|
-
expect(
|
894
|
-
expect(
|
895
|
-
expect(
|
944
|
+
expect(described_class.parse('2014-01-01')).to be_fed_holiday
|
945
|
+
expect(described_class.parse('2014-01-20')).to be_fed_holiday
|
946
|
+
expect(described_class.parse('2014-02-17')).to be_fed_holiday
|
947
|
+
expect(described_class.parse('2014-05-26')).to be_fed_holiday
|
948
|
+
expect(described_class.parse('2014-07-04')).to be_fed_holiday
|
949
|
+
expect(described_class.parse('2014-09-01')).to be_fed_holiday
|
950
|
+
expect(described_class.parse('2014-10-13')).to be_fed_holiday
|
951
|
+
expect(described_class.parse('2014-11-11')).to be_fed_holiday
|
952
|
+
expect(described_class.parse('2014-11-27')).to be_fed_holiday
|
953
|
+
expect(described_class.parse('2014-12-25')).to be_fed_holiday
|
896
954
|
# Not holidays
|
897
|
-
expect(
|
898
|
-
expect(
|
955
|
+
expect(described_class.parse('2014-02-14')).not_to be_fed_holiday
|
956
|
+
expect(described_class.parse('2014-04-18')).not_to be_fed_holiday
|
899
957
|
|
900
958
|
# For 2017:
|
901
959
|
# Monday, January 2 New Year's Day
|
@@ -908,47 +966,59 @@ describe Date do
|
|
908
966
|
# Friday, November 10 Veterans Day
|
909
967
|
# Thursday, November 23 Thanksgiving Day
|
910
968
|
# Monday, December 25 Christmas Day
|
911
|
-
expect(
|
912
|
-
expect(
|
913
|
-
expect(
|
914
|
-
expect(
|
915
|
-
expect(
|
916
|
-
expect(
|
917
|
-
expect(
|
918
|
-
expect(
|
919
|
-
expect(
|
920
|
-
expect(
|
969
|
+
expect(described_class.parse('2017-01-02')).to be_fed_holiday
|
970
|
+
expect(described_class.parse('2017-01-16')).to be_fed_holiday
|
971
|
+
expect(described_class.parse('2017-02-20')).to be_fed_holiday
|
972
|
+
expect(described_class.parse('2017-05-29')).to be_fed_holiday
|
973
|
+
expect(described_class.parse('2017-07-04')).to be_fed_holiday
|
974
|
+
expect(described_class.parse('2017-09-04')).to be_fed_holiday
|
975
|
+
expect(described_class.parse('2017-10-09')).to be_fed_holiday
|
976
|
+
expect(described_class.parse('2017-11-10')).to be_fed_holiday
|
977
|
+
expect(described_class.parse('2017-11-23')).to be_fed_holiday
|
978
|
+
expect(described_class.parse('2017-12-25')).to be_fed_holiday
|
921
979
|
|
922
980
|
# 2003 and 2008 had Christmas on Thur and this apparently makes
|
923
981
|
# the following Friday a holiday. I can't find any authority
|
924
982
|
# for this, but the government appeared to be shut down on these
|
925
983
|
# days.
|
926
|
-
expect(
|
927
|
-
expect(
|
984
|
+
expect(described_class.parse('2003-12-26')).to be_fed_holiday
|
985
|
+
expect(described_class.parse('2008-12-26')).to be_fed_holiday
|
928
986
|
|
929
987
|
# Some non-holidays
|
930
988
|
# New Year's Eve is /not/ a holiday unless on a weekend
|
931
989
|
# New Year's Eve on a Thursday
|
932
|
-
expect(
|
990
|
+
expect(described_class.parse('2015-12-31')).not_to be_fed_holiday
|
933
991
|
# New Year's Eve on a Saturday
|
934
|
-
expect(
|
992
|
+
expect(described_class.parse('2016-12-31')).to be_fed_holiday
|
935
993
|
# Monday
|
936
|
-
expect(
|
994
|
+
expect(described_class.parse('2014-11-17')).not_to be_fed_holiday
|
937
995
|
# Tuesday
|
938
|
-
expect(
|
996
|
+
expect(described_class.parse('2014-11-18')).not_to be_fed_holiday
|
939
997
|
# Wednesday
|
940
|
-
expect(
|
998
|
+
expect(described_class.parse('2014-11-19')).not_to be_fed_holiday
|
941
999
|
# Thursday
|
942
|
-
expect(
|
1000
|
+
expect(described_class.parse('2014-11-20')).not_to be_fed_holiday
|
943
1001
|
# Friday
|
944
|
-
expect(
|
1002
|
+
expect(described_class.parse('2014-11-21')).not_to be_fed_holiday
|
945
1003
|
|
946
1004
|
# Weekends are holidays, regardless
|
947
|
-
expect(
|
948
|
-
expect(
|
1005
|
+
expect(described_class.parse('2014-11-22')).to be_fed_holiday
|
1006
|
+
expect(described_class.parse('2014-11-23')).to be_fed_holiday
|
949
1007
|
end
|
950
1008
|
|
951
|
-
it '
|
1009
|
+
it 'knows that Juneteenth is a federal holiday from 2021' do
|
1010
|
+
expect(described_class.parse('2020-06-19')).not_to be_fed_holiday
|
1011
|
+
# Saturday
|
1012
|
+
expect(described_class.parse('2021-06-19')).to be_fed_holiday
|
1013
|
+
# Observed Friday
|
1014
|
+
expect(described_class.parse('2021-06-18')).to be_fed_holiday
|
1015
|
+
# Sunday
|
1016
|
+
expect(described_class.parse('2022-06-19')).to be_fed_holiday
|
1017
|
+
# Observed Monday
|
1018
|
+
expect(described_class.parse('2022-06-20')).to be_fed_holiday
|
1019
|
+
end
|
1020
|
+
|
1021
|
+
it 'knows if its an NYSE holiday' do
|
952
1022
|
################# 2014 2015 2016
|
953
1023
|
# New Year's Day January 1 January 1 January 1
|
954
1024
|
# Martin Luther King, Jr. Day January 20 January 19 January 18
|
@@ -959,191 +1029,191 @@ describe Date do
|
|
959
1029
|
# Labor Day September 1 September 7 September 5
|
960
1030
|
# Thanksgiving Day November 27 November 26 November 24
|
961
1031
|
# Christmas Day December 25 December 25 December 26
|
962
|
-
expect(
|
963
|
-
expect(
|
964
|
-
expect(
|
965
|
-
expect(
|
966
|
-
expect(
|
967
|
-
expect(
|
968
|
-
expect(
|
969
|
-
expect(
|
970
|
-
expect(
|
971
|
-
expect(
|
972
|
-
expect(
|
973
|
-
|
974
|
-
expect(
|
975
|
-
expect(
|
976
|
-
expect(
|
977
|
-
expect(
|
978
|
-
expect(
|
979
|
-
expect(
|
980
|
-
expect(
|
981
|
-
expect(
|
982
|
-
expect(
|
983
|
-
expect(
|
984
|
-
expect(
|
985
|
-
|
986
|
-
expect(
|
987
|
-
expect(
|
988
|
-
expect(
|
989
|
-
expect(
|
990
|
-
expect(
|
991
|
-
expect(
|
992
|
-
expect(
|
993
|
-
expect(
|
994
|
-
expect(
|
995
|
-
expect(
|
996
|
-
expect(
|
1032
|
+
expect(described_class.parse('2014-01-01')).to be_nyse_holiday
|
1033
|
+
expect(described_class.parse('2014-01-20')).to be_nyse_holiday
|
1034
|
+
expect(described_class.parse('2014-02-17')).to be_nyse_holiday
|
1035
|
+
expect(described_class.parse('2014-04-18')).to be_nyse_holiday
|
1036
|
+
expect(described_class.parse('2014-05-26')).to be_nyse_holiday
|
1037
|
+
expect(described_class.parse('2014-07-04')).to be_nyse_holiday
|
1038
|
+
expect(described_class.parse('2014-09-01')).to be_nyse_holiday
|
1039
|
+
expect(described_class.parse('2014-10-13')).not_to be_nyse_holiday
|
1040
|
+
expect(described_class.parse('2014-11-11')).not_to be_nyse_holiday
|
1041
|
+
expect(described_class.parse('2014-11-27')).to be_nyse_holiday
|
1042
|
+
expect(described_class.parse('2014-12-25')).to be_nyse_holiday
|
1043
|
+
|
1044
|
+
expect(described_class.parse('2015-01-01')).to be_nyse_holiday
|
1045
|
+
expect(described_class.parse('2015-01-19')).to be_nyse_holiday
|
1046
|
+
expect(described_class.parse('2015-02-16')).to be_nyse_holiday
|
1047
|
+
expect(described_class.parse('2015-04-03')).to be_nyse_holiday
|
1048
|
+
expect(described_class.parse('2015-05-25')).to be_nyse_holiday
|
1049
|
+
expect(described_class.parse('2015-07-03')).to be_nyse_holiday
|
1050
|
+
expect(described_class.parse('2015-09-07')).to be_nyse_holiday
|
1051
|
+
expect(described_class.parse('2015-10-13')).not_to be_nyse_holiday
|
1052
|
+
expect(described_class.parse('2015-11-11')).not_to be_nyse_holiday
|
1053
|
+
expect(described_class.parse('2015-11-26')).to be_nyse_holiday
|
1054
|
+
expect(described_class.parse('2015-12-25')).to be_nyse_holiday
|
1055
|
+
|
1056
|
+
expect(described_class.parse('2016-01-01')).to be_nyse_holiday
|
1057
|
+
expect(described_class.parse('2016-01-18')).to be_nyse_holiday
|
1058
|
+
expect(described_class.parse('2016-02-15')).to be_nyse_holiday
|
1059
|
+
expect(described_class.parse('2016-03-25')).to be_nyse_holiday
|
1060
|
+
expect(described_class.parse('2016-05-30')).to be_nyse_holiday
|
1061
|
+
expect(described_class.parse('2016-07-04')).to be_nyse_holiday
|
1062
|
+
expect(described_class.parse('2016-09-05')).to be_nyse_holiday
|
1063
|
+
expect(described_class.parse('2016-10-13')).not_to be_nyse_holiday
|
1064
|
+
expect(described_class.parse('2016-11-11')).not_to be_nyse_holiday
|
1065
|
+
expect(described_class.parse('2016-11-26')).to be_nyse_holiday
|
1066
|
+
expect(described_class.parse('2016-12-26')).to be_nyse_holiday
|
997
1067
|
|
998
1068
|
# Some non-holidays
|
999
1069
|
# Monday
|
1000
|
-
expect(
|
1070
|
+
expect(described_class.parse('2014-11-17')).not_to be_nyse_holiday
|
1001
1071
|
# Tuesday
|
1002
|
-
expect(
|
1072
|
+
expect(described_class.parse('2014-11-18')).not_to be_nyse_holiday
|
1003
1073
|
# Wednesday
|
1004
|
-
expect(
|
1074
|
+
expect(described_class.parse('2014-11-19')).not_to be_nyse_holiday
|
1005
1075
|
# Thursday
|
1006
|
-
expect(
|
1076
|
+
expect(described_class.parse('2014-11-20')).not_to be_nyse_holiday
|
1007
1077
|
# Friday
|
1008
|
-
expect(
|
1078
|
+
expect(described_class.parse('2014-11-21')).not_to be_nyse_holiday
|
1009
1079
|
|
1010
1080
|
# Weekends are holidays, regardless
|
1011
|
-
expect(
|
1012
|
-
expect(
|
1081
|
+
expect(described_class.parse('2014-11-22')).to be_nyse_holiday
|
1082
|
+
expect(described_class.parse('2014-11-23')).to be_nyse_holiday
|
1013
1083
|
|
1014
1084
|
# 9-11 Attacks
|
1015
|
-
expect(
|
1016
|
-
expect(
|
1085
|
+
expect(described_class.parse('2001-09-11')).to be_nyse_holiday
|
1086
|
+
expect(described_class.parse('2001-09-14')).to be_nyse_holiday
|
1017
1087
|
|
1018
1088
|
# 1968 Paperwork Crisis (Closed every Wed unless other holiday in
|
1019
1089
|
# week) from June 12 to December 31, 1968
|
1020
|
-
expect(
|
1021
|
-
expect(
|
1022
|
-
expect(
|
1090
|
+
expect(described_class.parse('1968-06-12')).to be_nyse_holiday
|
1091
|
+
expect(described_class.parse('1968-07-03')).not_to be_nyse_holiday
|
1092
|
+
expect(described_class.parse('1968-08-21')).to be_nyse_holiday
|
1023
1093
|
|
1024
1094
|
# Hurricane Sandy
|
1025
|
-
expect(
|
1026
|
-
expect(
|
1095
|
+
expect(described_class.parse('2012-10-29')).to be_nyse_holiday
|
1096
|
+
expect(described_class.parse('2012-10-30')).to be_nyse_holiday
|
1027
1097
|
|
1028
1098
|
# Death of President Ford
|
1029
|
-
expect(
|
1099
|
+
expect(described_class.parse('2007-01-02')).to be_nyse_holiday
|
1030
1100
|
end
|
1031
1101
|
|
1032
|
-
it '
|
1102
|
+
it 'knows if it is a Federal workday' do
|
1033
1103
|
# Some holidays
|
1034
|
-
expect(
|
1035
|
-
expect(
|
1036
|
-
expect(
|
1104
|
+
expect(described_class.parse('2017-02-20')).not_to be_fed_workday
|
1105
|
+
expect(described_class.parse('2017-05-29')).not_to be_fed_workday
|
1106
|
+
expect(described_class.parse('2017-07-04')).not_to be_fed_workday
|
1037
1107
|
|
1038
1108
|
# Some non-holidays
|
1039
1109
|
# Monday
|
1040
|
-
expect(
|
1110
|
+
expect(described_class.parse('2014-11-17')).to be_fed_workday
|
1041
1111
|
# Tuesday
|
1042
|
-
expect(
|
1112
|
+
expect(described_class.parse('2014-11-18')).to be_fed_workday
|
1043
1113
|
# Wednesday
|
1044
|
-
expect(
|
1114
|
+
expect(described_class.parse('2014-11-19')).to be_fed_workday
|
1045
1115
|
# Thursday
|
1046
|
-
expect(
|
1116
|
+
expect(described_class.parse('2014-11-20')).to be_fed_workday
|
1047
1117
|
# Friday
|
1048
|
-
expect(
|
1118
|
+
expect(described_class.parse('2014-11-21')).to be_fed_workday
|
1049
1119
|
|
1050
1120
|
# Weekends are holidays, regardless
|
1051
|
-
expect(
|
1052
|
-
expect(
|
1121
|
+
expect(described_class.parse('2014-11-22')).not_to be_fed_workday
|
1122
|
+
expect(described_class.parse('2014-11-23')).not_to be_fed_workday
|
1053
1123
|
end
|
1054
1124
|
|
1055
|
-
it '
|
1125
|
+
it 'knows if it is an NYSE workday' do
|
1056
1126
|
# Some holidays
|
1057
|
-
expect(
|
1058
|
-
expect(
|
1059
|
-
expect(
|
1127
|
+
expect(described_class.parse('2016-01-01')).not_to be_nyse_workday
|
1128
|
+
expect(described_class.parse('2016-01-18')).not_to be_nyse_workday
|
1129
|
+
expect(described_class.parse('2016-02-15')).not_to be_nyse_workday
|
1060
1130
|
|
1061
1131
|
# Some non-holidays
|
1062
1132
|
# Monday
|
1063
|
-
expect(
|
1133
|
+
expect(described_class.parse('2014-11-17')).to be_nyse_workday
|
1064
1134
|
# Tuesday
|
1065
|
-
expect(
|
1135
|
+
expect(described_class.parse('2014-11-18')).to be_nyse_workday
|
1066
1136
|
# Wednesday
|
1067
|
-
expect(
|
1137
|
+
expect(described_class.parse('2014-11-19')).to be_nyse_workday
|
1068
1138
|
# Thursday
|
1069
|
-
expect(
|
1139
|
+
expect(described_class.parse('2014-11-20')).to be_nyse_workday
|
1070
1140
|
# Friday
|
1071
|
-
expect(
|
1141
|
+
expect(described_class.parse('2014-11-21')).to be_nyse_workday
|
1072
1142
|
|
1073
1143
|
# Weekends are holidays, regardless
|
1074
|
-
expect(
|
1075
|
-
expect(
|
1144
|
+
expect(described_class.parse('2014-11-22')).not_to be_nyse_workday
|
1145
|
+
expect(described_class.parse('2014-11-23')).not_to be_nyse_workday
|
1076
1146
|
|
1077
1147
|
# Alias to trading_day?
|
1078
|
-
expect(
|
1079
|
-
expect(
|
1148
|
+
expect(described_class.parse('2014-11-22')).not_to be_trading_day
|
1149
|
+
expect(described_class.parse('2014-11-23')).not_to be_trading_day
|
1080
1150
|
end
|
1081
1151
|
|
1082
|
-
it '
|
1083
|
-
expect(
|
1084
|
-
.to eq
|
1085
|
-
expect(
|
1086
|
-
.to eq
|
1087
|
-
expect(
|
1088
|
-
.to eq
|
1152
|
+
it 'knows the next federal workday' do
|
1153
|
+
expect(described_class.parse('2015-12-31').next_fed_workday)
|
1154
|
+
.to eq described_class.parse('2016-01-04')
|
1155
|
+
expect(described_class.parse('2016-04-20').next_fed_workday)
|
1156
|
+
.to eq described_class.parse('2016-04-21')
|
1157
|
+
expect(described_class.parse('2016-04-22').next_fed_workday)
|
1158
|
+
.to eq described_class.parse('2016-04-25')
|
1089
1159
|
end
|
1090
1160
|
|
1091
|
-
it '
|
1092
|
-
expect(
|
1093
|
-
.to eq
|
1094
|
-
expect(
|
1095
|
-
.to eq
|
1096
|
-
expect(
|
1097
|
-
.to eq
|
1161
|
+
it 'knows the prior federal workday' do
|
1162
|
+
expect(described_class.parse('2016-01-04').prior_fed_workday)
|
1163
|
+
.to eq described_class.parse('2015-12-31')
|
1164
|
+
expect(described_class.parse('2016-04-21').prior_fed_workday)
|
1165
|
+
.to eq described_class.parse('2016-04-20')
|
1166
|
+
expect(described_class.parse('2016-04-25').prior_fed_workday)
|
1167
|
+
.to eq described_class.parse('2016-04-22')
|
1098
1168
|
end
|
1099
1169
|
|
1100
|
-
it '
|
1101
|
-
expect(
|
1102
|
-
.to eq
|
1103
|
-
expect(
|
1104
|
-
.to eq
|
1105
|
-
expect(
|
1106
|
-
.to eq
|
1107
|
-
expect(
|
1108
|
-
.to eq
|
1170
|
+
it 'knows the next NYSE workday' do
|
1171
|
+
expect(described_class.parse('2015-12-31').next_nyse_workday)
|
1172
|
+
.to eq described_class.parse('2016-01-04')
|
1173
|
+
expect(described_class.parse('2016-04-20').next_nyse_workday)
|
1174
|
+
.to eq described_class.parse('2016-04-21')
|
1175
|
+
expect(described_class.parse('2016-04-22').next_nyse_workday)
|
1176
|
+
.to eq described_class.parse('2016-04-25')
|
1177
|
+
expect(described_class.parse('2016-04-22').next_trading_day)
|
1178
|
+
.to eq described_class.parse('2016-04-25')
|
1109
1179
|
end
|
1110
1180
|
|
1111
|
-
it '
|
1181
|
+
it 'knows the prior NYSE workday' do
|
1112
1182
|
# The Monday after Easter; go to prior Thur since Good Friday
|
1113
1183
|
# is an NYSE holiday.
|
1114
|
-
expect(
|
1115
|
-
.to eq
|
1116
|
-
expect(
|
1117
|
-
.to eq
|
1118
|
-
expect(
|
1119
|
-
.to eq
|
1120
|
-
expect(
|
1121
|
-
.to eq
|
1122
|
-
expect(
|
1123
|
-
.to eq
|
1124
|
-
end
|
1125
|
-
|
1126
|
-
it '
|
1184
|
+
expect(described_class.parse('2014-04-21').prior_nyse_workday)
|
1185
|
+
.to eq described_class.parse('2014-04-17')
|
1186
|
+
expect(described_class.parse('2016-01-04').prior_nyse_workday)
|
1187
|
+
.to eq described_class.parse('2015-12-31')
|
1188
|
+
expect(described_class.parse('2016-04-21').prior_nyse_workday)
|
1189
|
+
.to eq described_class.parse('2016-04-20')
|
1190
|
+
expect(described_class.parse('2016-04-25').prior_nyse_workday)
|
1191
|
+
.to eq described_class.parse('2016-04-22')
|
1192
|
+
expect(described_class.parse('2016-04-25').prior_trading_day)
|
1193
|
+
.to eq described_class.parse('2016-04-22')
|
1194
|
+
end
|
1195
|
+
|
1196
|
+
it 'can skip until it hits a trading day' do
|
1127
1197
|
# A Wednesday
|
1128
|
-
expect(
|
1129
|
-
.to eq(
|
1198
|
+
expect(described_class.parse('2014-03-26').prior_until_trading_day)
|
1199
|
+
.to eq(described_class.parse('2014-03-26'))
|
1130
1200
|
# A Sunday
|
1131
|
-
expect(
|
1132
|
-
.to eq(
|
1201
|
+
expect(described_class.parse('2014-03-30').prior_until_trading_day)
|
1202
|
+
.to eq(described_class.parse('2014-03-28'))
|
1133
1203
|
# A Wednesday
|
1134
|
-
expect(
|
1135
|
-
.to eq(
|
1204
|
+
expect(described_class.parse('2014-03-26').next_until_trading_day)
|
1205
|
+
.to eq(described_class.parse('2014-03-26'))
|
1136
1206
|
# A Sunday
|
1137
|
-
expect(
|
1138
|
-
.to eq(
|
1207
|
+
expect(described_class.parse('2014-03-30').next_until_trading_day)
|
1208
|
+
.to eq(described_class.parse('2014-03-31'))
|
1139
1209
|
end
|
1140
1210
|
|
1141
|
-
it '
|
1211
|
+
it 'can add n trading days' do
|
1142
1212
|
# Add n trading days
|
1143
|
-
expect(
|
1144
|
-
.to eq(
|
1145
|
-
expect(
|
1146
|
-
.to eq(
|
1213
|
+
expect(described_class.parse('2014-03-30').add_trading_days(10))
|
1214
|
+
.to eq(described_class.parse('2014-04-11'))
|
1215
|
+
expect(described_class.parse('2014-03-30').add_trading_days(-10))
|
1216
|
+
.to eq(described_class.parse('2014-03-17'))
|
1147
1217
|
end
|
1148
1218
|
end
|
1149
1219
|
end
|