fat_core 4.12.0 → 4.13.0
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/string.rb +6 -67
- data/lib/fat_core/version.rb +1 -1
- data/spec/lib/array_spec.rb +1 -1
- data/spec/lib/bigdecimal_spec.rb +1 -1
- data/spec/lib/date_spec.rb +708 -709
- 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 +10 -5
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,683 +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
839
|
end
|
840
840
|
|
841
841
|
it "knows if it's within 6 months of another date if it's near end of month" do
|
842
842
|
# This tests for the Jammies Interntional twist where there is no
|
843
|
-
# corresponding day in the sixth month before or after the given
|
843
|
+
# corresponding day in the sixth month before or after the given described_class.
|
844
844
|
|
845
845
|
# Looking backward to Feb
|
846
|
-
expect(
|
847
|
-
.not_to be_within_6mos_of(
|
848
|
-
expect(
|
849
|
-
.not_to be_within_6mos_of(
|
850
|
-
expect(
|
851
|
-
.to be_within_6mos_of(
|
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
852
|
# Looking forward to Feb
|
853
|
-
expect(
|
854
|
-
.not_to be_within_6mos_of(
|
855
|
-
expect(
|
856
|
-
.not_to be_within_6mos_of(
|
857
|
-
expect(
|
858
|
-
.to be_within_6mos_of(
|
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
859
|
# Same in a leap year, backward
|
860
|
-
expect(
|
861
|
-
.not_to be_within_6mos_of(
|
862
|
-
expect(
|
863
|
-
.not_to be_within_6mos_of(
|
864
|
-
expect(
|
865
|
-
.to be_within_6mos_of(
|
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
866
|
# Same in a leap year, forward
|
867
|
-
expect(
|
868
|
-
.not_to be_within_6mos_of(
|
869
|
-
expect(
|
870
|
-
.not_to be_within_6mos_of(
|
871
|
-
expect(
|
872
|
-
.to be_within_6mos_of(
|
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
873
|
|
874
874
|
# Now try from October to April, as 31->30 test.
|
875
|
-
expect(
|
876
|
-
.not_to be_within_6mos_of(
|
877
|
-
expect(
|
878
|
-
.not_to be_within_6mos_of(
|
879
|
-
expect(
|
880
|
-
.to be_within_6mos_of(
|
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
881
|
# And forward
|
882
|
-
expect(
|
883
|
-
.not_to be_within_6mos_of(
|
884
|
-
expect(
|
885
|
-
.not_to be_within_6mos_of(
|
886
|
-
expect(
|
887
|
-
.to be_within_6mos_of(
|
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
888
|
|
889
889
|
# It's not symmetrical: notice the second example here is within six
|
890
890
|
# months if measured from April, but not if measured from October.
|
891
|
-
expect(
|
892
|
-
.not_to be_within_6mos_of(
|
893
|
-
expect(
|
894
|
-
.to be_within_6mos_of(
|
895
|
-
expect(
|
896
|
-
.to be_within_6mos_of(
|
897
|
-
|
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'))
|
898
897
|
end
|
899
898
|
end
|
900
899
|
|
901
900
|
describe 'holidays' do
|
902
|
-
it '
|
903
|
-
expect(
|
904
|
-
expect(
|
905
|
-
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
|
906
905
|
end
|
907
906
|
|
908
|
-
it '
|
907
|
+
it 'knows if its a federal holiday' do
|
909
908
|
# Got these from:
|
910
909
|
# http://www.opm.gov/policy-data-oversight/snow-dismissal-procedures/federal-holidays/
|
911
910
|
|
@@ -920,16 +919,16 @@ describe Date do
|
|
920
919
|
# Friday, November 11 Veterans Day
|
921
920
|
# Thursday, November 24 Thanksgiving Day
|
922
921
|
# Tuesday, December 26 *** Christmas Day
|
923
|
-
expect(
|
924
|
-
expect(
|
925
|
-
expect(
|
926
|
-
expect(
|
927
|
-
expect(
|
928
|
-
expect(
|
929
|
-
expect(
|
930
|
-
expect(
|
931
|
-
expect(
|
932
|
-
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
|
933
932
|
|
934
933
|
# For 2014:
|
935
934
|
# Wednesday, January 1 New Year's Day
|
@@ -942,19 +941,19 @@ describe Date do
|
|
942
941
|
# Tuesday, November 11 Veterans Day
|
943
942
|
# Thursday, November 27 Thanksgiving Day
|
944
943
|
# Thursday, December 25 Christmas Day
|
945
|
-
expect(
|
946
|
-
expect(
|
947
|
-
expect(
|
948
|
-
expect(
|
949
|
-
expect(
|
950
|
-
expect(
|
951
|
-
expect(
|
952
|
-
expect(
|
953
|
-
expect(
|
954
|
-
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
|
955
954
|
# Not holidays
|
956
|
-
expect(
|
957
|
-
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
|
958
957
|
|
959
958
|
# For 2017:
|
960
959
|
# Monday, January 2 New Year's Day
|
@@ -967,59 +966,59 @@ describe Date do
|
|
967
966
|
# Friday, November 10 Veterans Day
|
968
967
|
# Thursday, November 23 Thanksgiving Day
|
969
968
|
# Monday, December 25 Christmas Day
|
970
|
-
expect(
|
971
|
-
expect(
|
972
|
-
expect(
|
973
|
-
expect(
|
974
|
-
expect(
|
975
|
-
expect(
|
976
|
-
expect(
|
977
|
-
expect(
|
978
|
-
expect(
|
979
|
-
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
|
980
979
|
|
981
980
|
# 2003 and 2008 had Christmas on Thur and this apparently makes
|
982
981
|
# the following Friday a holiday. I can't find any authority
|
983
982
|
# for this, but the government appeared to be shut down on these
|
984
983
|
# days.
|
985
|
-
expect(
|
986
|
-
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
|
987
986
|
|
988
987
|
# Some non-holidays
|
989
988
|
# New Year's Eve is /not/ a holiday unless on a weekend
|
990
989
|
# New Year's Eve on a Thursday
|
991
|
-
expect(
|
990
|
+
expect(described_class.parse('2015-12-31')).not_to be_fed_holiday
|
992
991
|
# New Year's Eve on a Saturday
|
993
|
-
expect(
|
992
|
+
expect(described_class.parse('2016-12-31')).to be_fed_holiday
|
994
993
|
# Monday
|
995
|
-
expect(
|
994
|
+
expect(described_class.parse('2014-11-17')).not_to be_fed_holiday
|
996
995
|
# Tuesday
|
997
|
-
expect(
|
996
|
+
expect(described_class.parse('2014-11-18')).not_to be_fed_holiday
|
998
997
|
# Wednesday
|
999
|
-
expect(
|
998
|
+
expect(described_class.parse('2014-11-19')).not_to be_fed_holiday
|
1000
999
|
# Thursday
|
1001
|
-
expect(
|
1000
|
+
expect(described_class.parse('2014-11-20')).not_to be_fed_holiday
|
1002
1001
|
# Friday
|
1003
|
-
expect(
|
1002
|
+
expect(described_class.parse('2014-11-21')).not_to be_fed_holiday
|
1004
1003
|
|
1005
1004
|
# Weekends are holidays, regardless
|
1006
|
-
expect(
|
1007
|
-
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
|
1008
1007
|
end
|
1009
1008
|
|
1010
1009
|
it 'knows that Juneteenth is a federal holiday from 2021' do
|
1011
|
-
expect(
|
1010
|
+
expect(described_class.parse('2020-06-19')).not_to be_fed_holiday
|
1012
1011
|
# Saturday
|
1013
|
-
expect(
|
1012
|
+
expect(described_class.parse('2021-06-19')).to be_fed_holiday
|
1014
1013
|
# Observed Friday
|
1015
|
-
expect(
|
1014
|
+
expect(described_class.parse('2021-06-18')).to be_fed_holiday
|
1016
1015
|
# Sunday
|
1017
|
-
expect(
|
1016
|
+
expect(described_class.parse('2022-06-19')).to be_fed_holiday
|
1018
1017
|
# Observed Monday
|
1019
|
-
expect(
|
1018
|
+
expect(described_class.parse('2022-06-20')).to be_fed_holiday
|
1020
1019
|
end
|
1021
1020
|
|
1022
|
-
it '
|
1021
|
+
it 'knows if its an NYSE holiday' do
|
1023
1022
|
################# 2014 2015 2016
|
1024
1023
|
# New Year's Day January 1 January 1 January 1
|
1025
1024
|
# Martin Luther King, Jr. Day January 20 January 19 January 18
|
@@ -1030,191 +1029,191 @@ describe Date do
|
|
1030
1029
|
# Labor Day September 1 September 7 September 5
|
1031
1030
|
# Thanksgiving Day November 27 November 26 November 24
|
1032
1031
|
# Christmas Day December 25 December 25 December 26
|
1033
|
-
expect(
|
1034
|
-
expect(
|
1035
|
-
expect(
|
1036
|
-
expect(
|
1037
|
-
expect(
|
1038
|
-
expect(
|
1039
|
-
expect(
|
1040
|
-
expect(
|
1041
|
-
expect(
|
1042
|
-
expect(
|
1043
|
-
expect(
|
1044
|
-
|
1045
|
-
expect(
|
1046
|
-
expect(
|
1047
|
-
expect(
|
1048
|
-
expect(
|
1049
|
-
expect(
|
1050
|
-
expect(
|
1051
|
-
expect(
|
1052
|
-
expect(
|
1053
|
-
expect(
|
1054
|
-
expect(
|
1055
|
-
expect(
|
1056
|
-
|
1057
|
-
expect(
|
1058
|
-
expect(
|
1059
|
-
expect(
|
1060
|
-
expect(
|
1061
|
-
expect(
|
1062
|
-
expect(
|
1063
|
-
expect(
|
1064
|
-
expect(
|
1065
|
-
expect(
|
1066
|
-
expect(
|
1067
|
-
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
|
1068
1067
|
|
1069
1068
|
# Some non-holidays
|
1070
1069
|
# Monday
|
1071
|
-
expect(
|
1070
|
+
expect(described_class.parse('2014-11-17')).not_to be_nyse_holiday
|
1072
1071
|
# Tuesday
|
1073
|
-
expect(
|
1072
|
+
expect(described_class.parse('2014-11-18')).not_to be_nyse_holiday
|
1074
1073
|
# Wednesday
|
1075
|
-
expect(
|
1074
|
+
expect(described_class.parse('2014-11-19')).not_to be_nyse_holiday
|
1076
1075
|
# Thursday
|
1077
|
-
expect(
|
1076
|
+
expect(described_class.parse('2014-11-20')).not_to be_nyse_holiday
|
1078
1077
|
# Friday
|
1079
|
-
expect(
|
1078
|
+
expect(described_class.parse('2014-11-21')).not_to be_nyse_holiday
|
1080
1079
|
|
1081
1080
|
# Weekends are holidays, regardless
|
1082
|
-
expect(
|
1083
|
-
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
|
1084
1083
|
|
1085
1084
|
# 9-11 Attacks
|
1086
|
-
expect(
|
1087
|
-
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
|
1088
1087
|
|
1089
1088
|
# 1968 Paperwork Crisis (Closed every Wed unless other holiday in
|
1090
1089
|
# week) from June 12 to December 31, 1968
|
1091
|
-
expect(
|
1092
|
-
expect(
|
1093
|
-
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
|
1094
1093
|
|
1095
1094
|
# Hurricane Sandy
|
1096
|
-
expect(
|
1097
|
-
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
|
1098
1097
|
|
1099
1098
|
# Death of President Ford
|
1100
|
-
expect(
|
1099
|
+
expect(described_class.parse('2007-01-02')).to be_nyse_holiday
|
1101
1100
|
end
|
1102
1101
|
|
1103
|
-
it '
|
1102
|
+
it 'knows if it is a Federal workday' do
|
1104
1103
|
# Some holidays
|
1105
|
-
expect(
|
1106
|
-
expect(
|
1107
|
-
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
|
1108
1107
|
|
1109
1108
|
# Some non-holidays
|
1110
1109
|
# Monday
|
1111
|
-
expect(
|
1110
|
+
expect(described_class.parse('2014-11-17')).to be_fed_workday
|
1112
1111
|
# Tuesday
|
1113
|
-
expect(
|
1112
|
+
expect(described_class.parse('2014-11-18')).to be_fed_workday
|
1114
1113
|
# Wednesday
|
1115
|
-
expect(
|
1114
|
+
expect(described_class.parse('2014-11-19')).to be_fed_workday
|
1116
1115
|
# Thursday
|
1117
|
-
expect(
|
1116
|
+
expect(described_class.parse('2014-11-20')).to be_fed_workday
|
1118
1117
|
# Friday
|
1119
|
-
expect(
|
1118
|
+
expect(described_class.parse('2014-11-21')).to be_fed_workday
|
1120
1119
|
|
1121
1120
|
# Weekends are holidays, regardless
|
1122
|
-
expect(
|
1123
|
-
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
|
1124
1123
|
end
|
1125
1124
|
|
1126
|
-
it '
|
1125
|
+
it 'knows if it is an NYSE workday' do
|
1127
1126
|
# Some holidays
|
1128
|
-
expect(
|
1129
|
-
expect(
|
1130
|
-
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
|
1131
1130
|
|
1132
1131
|
# Some non-holidays
|
1133
1132
|
# Monday
|
1134
|
-
expect(
|
1133
|
+
expect(described_class.parse('2014-11-17')).to be_nyse_workday
|
1135
1134
|
# Tuesday
|
1136
|
-
expect(
|
1135
|
+
expect(described_class.parse('2014-11-18')).to be_nyse_workday
|
1137
1136
|
# Wednesday
|
1138
|
-
expect(
|
1137
|
+
expect(described_class.parse('2014-11-19')).to be_nyse_workday
|
1139
1138
|
# Thursday
|
1140
|
-
expect(
|
1139
|
+
expect(described_class.parse('2014-11-20')).to be_nyse_workday
|
1141
1140
|
# Friday
|
1142
|
-
expect(
|
1141
|
+
expect(described_class.parse('2014-11-21')).to be_nyse_workday
|
1143
1142
|
|
1144
1143
|
# Weekends are holidays, regardless
|
1145
|
-
expect(
|
1146
|
-
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
|
1147
1146
|
|
1148
1147
|
# Alias to trading_day?
|
1149
|
-
expect(
|
1150
|
-
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
|
1151
1150
|
end
|
1152
1151
|
|
1153
|
-
it '
|
1154
|
-
expect(
|
1155
|
-
.to eq
|
1156
|
-
expect(
|
1157
|
-
.to eq
|
1158
|
-
expect(
|
1159
|
-
.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')
|
1160
1159
|
end
|
1161
1160
|
|
1162
|
-
it '
|
1163
|
-
expect(
|
1164
|
-
.to eq
|
1165
|
-
expect(
|
1166
|
-
.to eq
|
1167
|
-
expect(
|
1168
|
-
.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')
|
1169
1168
|
end
|
1170
1169
|
|
1171
|
-
it '
|
1172
|
-
expect(
|
1173
|
-
.to eq
|
1174
|
-
expect(
|
1175
|
-
.to eq
|
1176
|
-
expect(
|
1177
|
-
.to eq
|
1178
|
-
expect(
|
1179
|
-
.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')
|
1180
1179
|
end
|
1181
1180
|
|
1182
|
-
it '
|
1181
|
+
it 'knows the prior NYSE workday' do
|
1183
1182
|
# The Monday after Easter; go to prior Thur since Good Friday
|
1184
1183
|
# is an NYSE holiday.
|
1185
|
-
expect(
|
1186
|
-
.to eq
|
1187
|
-
expect(
|
1188
|
-
.to eq
|
1189
|
-
expect(
|
1190
|
-
.to eq
|
1191
|
-
expect(
|
1192
|
-
.to eq
|
1193
|
-
expect(
|
1194
|
-
.to eq
|
1195
|
-
end
|
1196
|
-
|
1197
|
-
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
|
1198
1197
|
# A Wednesday
|
1199
|
-
expect(
|
1200
|
-
.to eq(
|
1198
|
+
expect(described_class.parse('2014-03-26').prior_until_trading_day)
|
1199
|
+
.to eq(described_class.parse('2014-03-26'))
|
1201
1200
|
# A Sunday
|
1202
|
-
expect(
|
1203
|
-
.to eq(
|
1201
|
+
expect(described_class.parse('2014-03-30').prior_until_trading_day)
|
1202
|
+
.to eq(described_class.parse('2014-03-28'))
|
1204
1203
|
# A Wednesday
|
1205
|
-
expect(
|
1206
|
-
.to eq(
|
1204
|
+
expect(described_class.parse('2014-03-26').next_until_trading_day)
|
1205
|
+
.to eq(described_class.parse('2014-03-26'))
|
1207
1206
|
# A Sunday
|
1208
|
-
expect(
|
1209
|
-
.to eq(
|
1207
|
+
expect(described_class.parse('2014-03-30').next_until_trading_day)
|
1208
|
+
.to eq(described_class.parse('2014-03-31'))
|
1210
1209
|
end
|
1211
1210
|
|
1212
|
-
it '
|
1211
|
+
it 'can add n trading days' do
|
1213
1212
|
# Add n trading days
|
1214
|
-
expect(
|
1215
|
-
.to eq(
|
1216
|
-
expect(
|
1217
|
-
.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'))
|
1218
1217
|
end
|
1219
1218
|
end
|
1220
1219
|
end
|