by_star 4.0.0 → 4.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/mysql.yml +92 -92
  3. data/.github/workflows/postgresql.yml +99 -99
  4. data/.gitignore +6 -6
  5. data/.travis.yml +92 -92
  6. data/CHANGELOG.md +63 -59
  7. data/Gemfile +18 -18
  8. data/MIT-LICENSE +20 -20
  9. data/README.md +616 -616
  10. data/Rakefile +18 -18
  11. data/UPGRADING +4 -4
  12. data/by_star.gemspec +34 -34
  13. data/cleaner.rb +24 -24
  14. data/lib/by_star/base.rb +69 -69
  15. data/lib/by_star/between.rb +185 -185
  16. data/lib/by_star/directional.rb +35 -35
  17. data/lib/by_star/kernel/date.rb +41 -41
  18. data/lib/by_star/kernel/in_time_zone.rb +20 -20
  19. data/lib/by_star/kernel/time.rb +41 -41
  20. data/lib/by_star/normalization.rb +156 -156
  21. data/lib/by_star/orm/active_record/by_star.rb +75 -75
  22. data/lib/by_star/orm/mongoid/by_star.rb +90 -90
  23. data/lib/by_star/orm/mongoid/reorder.rb +23 -23
  24. data/lib/by_star/version.rb +3 -3
  25. data/lib/by_star.rb +18 -18
  26. data/spec/database.yml +15 -15
  27. data/spec/fixtures/active_record/models.rb +12 -12
  28. data/spec/fixtures/active_record/schema.rb +19 -19
  29. data/spec/fixtures/mongoid/models.rb +31 -31
  30. data/spec/fixtures/shared/seeds.rb +36 -36
  31. data/spec/gemfiles/Gemfile.rails +5 -5
  32. data/spec/gemfiles/Gemfile.rails32 +7 -7
  33. data/spec/gemfiles/Gemfile.rails40 +7 -7
  34. data/spec/gemfiles/Gemfile.rails41 +7 -7
  35. data/spec/gemfiles/Gemfile.rails42 +7 -7
  36. data/spec/gemfiles/Gemfile.rails50 +7 -7
  37. data/spec/gemfiles/Gemfile.rails51 +7 -7
  38. data/spec/gemfiles/Gemfile.rails52 +7 -7
  39. data/spec/gemfiles/Gemfile.rails60 +7 -7
  40. data/spec/gemfiles/Gemfile.rails61 +7 -7
  41. data/spec/integration/active_record/active_record_spec.rb +41 -41
  42. data/spec/integration/mongoid/mongoid_spec.rb +39 -39
  43. data/spec/integration/shared/at_time.rb +53 -53
  44. data/spec/integration/shared/between_dates.rb +99 -99
  45. data/spec/integration/shared/between_times.rb +99 -99
  46. data/spec/integration/shared/by_calendar_month.rb +55 -55
  47. data/spec/integration/shared/by_cweek.rb +54 -54
  48. data/spec/integration/shared/by_day.rb +120 -120
  49. data/spec/integration/shared/by_direction.rb +126 -126
  50. data/spec/integration/shared/by_fortnight.rb +48 -48
  51. data/spec/integration/shared/by_month.rb +50 -50
  52. data/spec/integration/shared/by_quarter.rb +49 -49
  53. data/spec/integration/shared/by_week.rb +54 -54
  54. data/spec/integration/shared/by_weekend.rb +49 -49
  55. data/spec/integration/shared/by_year.rb +48 -48
  56. data/spec/integration/shared/index_scope_parameter.rb +111 -111
  57. data/spec/integration/shared/offset_parameter.rb +32 -32
  58. data/spec/integration/shared/order_parameter.rb +36 -36
  59. data/spec/integration/shared/relative.rb +174 -174
  60. data/spec/spec_helper.rb +33 -33
  61. data/spec/unit/kernel_date_spec.rb +113 -113
  62. data/spec/unit/kernel_time_spec.rb +57 -57
  63. data/spec/unit/normalization_spec.rb +384 -384
  64. data/tmp/.gitignore +1 -1
  65. metadata +3 -3
@@ -1,384 +1,384 @@
1
- require 'spec_helper'
2
-
3
- describe ByStar::Normalization do
4
-
5
- let(:options){ {} }
6
-
7
- shared_examples_for 'date normalization from string' do
8
-
9
- context 'when Chronic is defined' do
10
-
11
- context 'date String' do
12
- let(:input){ '2014-01-01' }
13
- it { should eq Date.parse('2014-01-01') }
14
- end
15
-
16
- context 'time String' do
17
- let(:input){ '2014-01-01 15:00:00' }
18
- it { should eq Date.parse('2014-01-01') }
19
- end
20
-
21
- context 'natural language String' do
22
- let(:input){ 'tomorrow at 3:30 pm' }
23
- it { should eq Date.parse('2014-01-02') }
24
- end
25
- end
26
-
27
- context 'when Chronic is not defined' do
28
-
29
- before { hide_const('Chronic') }
30
-
31
- context 'date String' do
32
- let(:input){ '2014-01-01' }
33
- it { should eq Date.parse('2014-01-01') }
34
- end
35
-
36
- context 'time String' do
37
- let(:input){ '2014-01-01 15:00:00' }
38
- it { should eq Date.parse('2014-01-01') }
39
- end
40
-
41
- context 'natural language String' do
42
- let(:input){ 'tomorrow at noon' }
43
- it { expect{ subject }.to raise_error(ByStar::ParseError, "Cannot parse String #{input.inspect}") }
44
- end
45
- end
46
- end
47
-
48
- shared_examples_for 'date normalization from time value' do
49
- context 'Date' do
50
- let(:input){ Date.parse('2014-01-01') }
51
- it { expect eq Date.parse('2014-01-01') }
52
- end
53
-
54
- context 'DateTime' do
55
- let(:input){ Date.parse('2014-01-01').to_datetime }
56
- it { expect eq Date.parse('2014-01-01') }
57
- end
58
-
59
- context 'Time' do
60
- let(:input){ Date.parse('2014-01-01') }
61
- it { expect eq Date.parse('2014-01-01') }
62
- end
63
- end
64
-
65
- describe '#time' do
66
- subject { ByStar::Normalization.time(input) }
67
-
68
- context 'when Chronic is defined' do
69
-
70
- context 'date String' do
71
- let(:input){ '2014-01-01' }
72
- it { should eq Time.zone.parse('2014-01-01 12:00:00') }
73
- end
74
-
75
- context 'time String' do
76
- let(:input){ '2014-01-01 15:00:00' }
77
- it { should eq Time.zone.parse('2014-01-01 15:00:00') }
78
- end
79
-
80
- context 'natural language String' do
81
- let(:input){ 'tomorrow at 3:30 pm' }
82
- it { should eq Time.zone.parse('2014-01-02 15:30:00') }
83
- end
84
- end
85
-
86
- context 'when Chronic is not defined' do
87
-
88
- before { hide_const('Chronic') }
89
-
90
- context 'date String' do
91
- let(:input){ '2014-01-01' }
92
- it { should eq Time.zone.parse('2014-01-01 00:00:00') }
93
- end
94
-
95
- context 'time String' do
96
- let(:input){ '2014-01-01 15:00:00' }
97
- it { should eq Time.zone.parse('2014-01-01 15:00:00') }
98
- end
99
-
100
- context 'natural language String' do
101
- let(:input){ 'tomorrow at noon' }
102
- it { expect{ subject }.to raise_error(ByStar::ParseError, "Cannot parse String #{input.inspect}") }
103
- end
104
- end
105
-
106
- context 'Date' do
107
- let(:input){ Date.parse('2014-01-01') }
108
- it { expect eq Time.zone.parse('2014-01-01 00:00:00') }
109
- end
110
-
111
- context 'DateTime' do
112
- let(:input){ Time.zone.parse('2014-01-01 15:00:00').to_datetime }
113
- it { expect eq Time.zone.parse('2014-01-01 15:00:00') }
114
- end
115
-
116
- context 'Time' do
117
- let(:input){ Time.zone.parse('2014-01-01 15:00:00') }
118
- it { expect eq Time.zone.parse('2014-01-01 15:00:00') }
119
- end
120
- end
121
-
122
- describe '#week' do
123
- subject { ByStar::Normalization.week(input, options) }
124
- it_behaves_like 'date normalization from string'
125
- it_behaves_like 'date normalization from time value'
126
-
127
- context 'Integer -1' do
128
- let(:input){ -1 }
129
- it { expect{subject}.to raise_error(ByStar::ParseError, 'Week number must be between 0 and 52') }
130
- end
131
-
132
- context 'Integer 0' do
133
- let(:input){ 0 }
134
- it { expect eq Date.parse('2014-01-01') }
135
- end
136
-
137
- context 'Integer 20' do
138
- let(:input){ 20 }
139
- it { expect eq Date.parse('2014-05-21') }
140
- end
141
-
142
- context 'Integer 53' do
143
- let(:input){ 53 }
144
- it { expect{subject}.to raise_error(ByStar::ParseError, 'Week number must be between 0 and 52') }
145
- end
146
-
147
- context 'with year option' do
148
- let(:options){ { year: 2011 } }
149
-
150
- context 'Integer 0' do
151
- let(:input){ 0 }
152
- it { expect eq Date.parse('2011-01-01') }
153
- end
154
-
155
- context 'Integer 20' do
156
- let(:input){ 20 }
157
- it { expect eq Date.parse('2011-05-21') }
158
- end
159
- end
160
- end
161
-
162
- describe '#cweek' do
163
- subject { ByStar::Normalization.cweek(input, options) }
164
- it_behaves_like 'date normalization from string'
165
- it_behaves_like 'date normalization from time value'
166
-
167
- context 'Integer 9' do
168
- let(:input){ 0 }
169
- it { expect{subject}.to raise_error(ByStar::ParseError, 'cweek number must be between 1 and 53') }
170
- end
171
-
172
- context 'Integer 1' do
173
- let(:input){ 1 }
174
- it { expect eq Date.parse('2014-01-01') }
175
- end
176
-
177
- context 'Integer 21' do
178
- let(:input){ 21 }
179
- it { expect eq Date.parse('2014-05-21') }
180
- end
181
-
182
- context 'Integer 54' do
183
- let(:input){ 54 }
184
- it { expect{subject}.to raise_error(ByStar::ParseError, 'cweek number must be between 1 and 53') }
185
- end
186
-
187
- context 'with year option' do
188
- let(:options){ { year: 2011 } }
189
-
190
- context 'Integer 1' do
191
- let(:input){ 1 }
192
- it { expect eq Date.parse('2011-01-01') }
193
- end
194
-
195
- context 'Integer 21' do
196
- let(:input){ 21 }
197
- it { expect eq Date.parse('2011-05-21') }
198
- end
199
- end
200
- end
201
-
202
- describe '#fortnight' do
203
- subject { ByStar::Normalization.fortnight(input, options) }
204
- it_behaves_like 'date normalization from string'
205
- it_behaves_like 'date normalization from time value'
206
-
207
- context 'Integer 0' do
208
- let(:input){ 0 }
209
- it { expect eq Date.parse('2014-01-01') }
210
- end
211
-
212
- context 'Integer 26' do
213
- let(:input){ 26 }
214
- it { expect eq Date.parse('2014-12-31') }
215
- end
216
-
217
- context 'out of range' do
218
- specify { expect{ ByStar::Normalization.fortnight(-1) }.to raise_error(ByStar::ParseError, 'Fortnight number must be between 0 and 26') }
219
- specify { expect{ ByStar::Normalization.fortnight(27) }.to raise_error(ByStar::ParseError, 'Fortnight number must be between 0 and 26') }
220
- end
221
-
222
- context 'with year option' do
223
- let(:options){ { year: 2011 } }
224
-
225
- context 'Integer 0' do
226
- let(:input){ 0 }
227
- it { expect eq Date.parse('2011-01-01') }
228
- end
229
-
230
- context 'Integer 26' do
231
- let(:input){ 26 }
232
- it { expect eq Date.parse('2011-12-31') }
233
- end
234
- end
235
- end
236
-
237
- describe '#month' do
238
- subject { ByStar::Normalization.month(input, options) }
239
- it_behaves_like 'date normalization from time value'
240
-
241
- context 'month abbr String' do
242
- let(:input){ 'Feb' }
243
- it { expect eq Date.parse('2014-02-01') }
244
- end
245
-
246
- context 'month full String' do
247
- let(:input){ 'February' }
248
- it { expect eq Date.parse('2014-02-01') }
249
- end
250
-
251
- context 'number String' do
252
- let(:input){ '2' }
253
- it { expect eq Date.parse('2014-02-01') }
254
- end
255
-
256
- context 'Integer' do
257
- let(:input){ 2 }
258
- it { expect eq Date.parse('2014-02-01') }
259
- end
260
-
261
- context 'out of range' do
262
- specify { expect{ ByStar::Normalization.month(0) }.to raise_error(ByStar::ParseError, 'Month must be a number between 1 and 12 or a month name') }
263
- specify { expect{ ByStar::Normalization.month(13) }.to raise_error(ByStar::ParseError, 'Month must be a number between 1 and 12 or a month name') }
264
- end
265
-
266
- context 'with year option' do
267
- let(:options){ { year: 2011 } }
268
-
269
- context 'month abbr String' do
270
- let(:input){ 'Dec' }
271
- it { expect eq Date.parse('2011-12-01') }
272
- end
273
-
274
- context 'Integer 12' do
275
- let(:input){ 10 }
276
- it { expect eq Date.parse('2011-10-01') }
277
- end
278
- end
279
- end
280
-
281
- describe '#quarter' do
282
- subject { ByStar::Normalization.quarter(input, options) }
283
- it_behaves_like 'date normalization from string'
284
- it_behaves_like 'date normalization from time value'
285
-
286
- context 'Integer 1' do
287
- let(:input){ 1 }
288
- it { expect eq Date.parse('2014-01-01') }
289
- end
290
-
291
- context 'Integer 2' do
292
- let(:input){ 2 }
293
- it { expect eq Date.parse('2014-04-01') }
294
- end
295
-
296
- context 'Integer 3' do
297
- let(:input){ 3 }
298
- it { expect eq Date.parse('2014-07-01') }
299
- end
300
-
301
- context 'Integer 4' do
302
- let(:input){ 4 }
303
- it { expect eq Date.parse('2014-10-01') }
304
- end
305
-
306
- context 'with year option' do
307
- let(:options){ { year: 2011 } }
308
-
309
- context 'Integer 3' do
310
- let(:input){ 3 }
311
- it { expect eq Date.parse('2011-07-01') }
312
- end
313
- end
314
-
315
- context 'out of range' do
316
- specify { expect{ ByStar::Normalization.quarter(0) }.to raise_error(ByStar::ParseError, 'Quarter number must be between 1 and 4') }
317
- specify { expect{ ByStar::Normalization.quarter(5) }.to raise_error(ByStar::ParseError, 'Quarter number must be between 1 and 4') }
318
- end
319
- end
320
-
321
- describe '#year' do
322
- subject { ByStar::Normalization.year(input, options) }
323
- it_behaves_like 'date normalization from string'
324
- it_behaves_like 'date normalization from time value'
325
-
326
- context 'Integer 69' do
327
- let(:input){ 69 }
328
- it { expect eq Date.parse('2069-01-01') }
329
- end
330
-
331
- context 'Integer 99' do
332
- let(:input){ 99 }
333
- it { expect eq Date.parse('1999-01-01') }
334
- end
335
-
336
- context 'Integer 2001' do
337
- let(:input){ 1 }
338
- it { expect eq Date.parse('2001-01-01') }
339
- end
340
-
341
- context 'String 01' do
342
- let(:input){ '01' }
343
- it { expect eq Date.parse('2001-01-01') }
344
- end
345
-
346
- context 'String 70' do
347
- let(:input){ '70' }
348
- it { expect eq Date.parse('1970-01-01') }
349
- end
350
-
351
- context 'String 2001' do
352
- let(:input){ '2001' }
353
- it { expect eq Date.parse('2001-01-01') }
354
- end
355
- end
356
-
357
- describe '#time_in_units' do
358
- subject { ByStar::Normalization.time_in_units(input) }
359
-
360
- context 'when less than a day' do
361
- let(:input) { 34876 }
362
- it { is_expected.to eq(days: 0, hour: 9, min: 41, sec: 16) }
363
- end
364
-
365
- context 'when more than a day' do
366
- let(:input) { 97532 }
367
- it { is_expected.to eq(days: 1, hour: 3, min: 5, sec: 32) }
368
- end
369
- end
370
-
371
- describe '#apply_offset_start' do
372
- subject { ByStar::Normalization.apply_offset_start(input, offset) }
373
- let(:input) { Time.zone.parse('2020-04-05 00:00:00') }
374
- let(:offset) { 5.hours }
375
- it { is_expected.to eq Time.zone.parse('2020-04-05 05:00:00') }
376
- end
377
-
378
- describe '#apply_offset_end' do
379
- subject { ByStar::Normalization.apply_offset_end(input, offset) }
380
- let(:input) { Time.zone.parse('2020-10-04 00:00:00') }
381
- let(:offset) { 5.hours }
382
- it { is_expected.to eq Time.zone.parse('2020-10-05 04:59:59') }
383
- end
384
- end
1
+ require 'spec_helper'
2
+
3
+ describe ByStar::Normalization do
4
+
5
+ let(:options){ {} }
6
+
7
+ shared_examples_for 'date normalization from string' do
8
+
9
+ context 'when Chronic is defined' do
10
+
11
+ context 'date String' do
12
+ let(:input){ '2014-01-01' }
13
+ it { should eq Date.parse('2014-01-01') }
14
+ end
15
+
16
+ context 'time String' do
17
+ let(:input){ '2014-01-01 15:00:00' }
18
+ it { should eq Date.parse('2014-01-01') }
19
+ end
20
+
21
+ context 'natural language String' do
22
+ let(:input){ 'tomorrow at 3:30 pm' }
23
+ it { should eq Date.parse('2014-01-02') }
24
+ end
25
+ end
26
+
27
+ context 'when Chronic is not defined' do
28
+
29
+ before { hide_const('Chronic') }
30
+
31
+ context 'date String' do
32
+ let(:input){ '2014-01-01' }
33
+ it { should eq Date.parse('2014-01-01') }
34
+ end
35
+
36
+ context 'time String' do
37
+ let(:input){ '2014-01-01 15:00:00' }
38
+ it { should eq Date.parse('2014-01-01') }
39
+ end
40
+
41
+ context 'natural language String' do
42
+ let(:input){ 'tomorrow at noon' }
43
+ it { expect{ subject }.to raise_error(ByStar::ParseError, "Cannot parse String #{input.inspect}") }
44
+ end
45
+ end
46
+ end
47
+
48
+ shared_examples_for 'date normalization from time value' do
49
+ context 'Date' do
50
+ let(:input){ Date.parse('2014-01-01') }
51
+ it { expect eq Date.parse('2014-01-01') }
52
+ end
53
+
54
+ context 'DateTime' do
55
+ let(:input){ Date.parse('2014-01-01').to_datetime }
56
+ it { expect eq Date.parse('2014-01-01') }
57
+ end
58
+
59
+ context 'Time' do
60
+ let(:input){ Date.parse('2014-01-01') }
61
+ it { expect eq Date.parse('2014-01-01') }
62
+ end
63
+ end
64
+
65
+ describe '#time' do
66
+ subject { ByStar::Normalization.time(input) }
67
+
68
+ context 'when Chronic is defined' do
69
+
70
+ context 'date String' do
71
+ let(:input){ '2014-01-01' }
72
+ it { should eq Time.zone.parse('2014-01-01 12:00:00') }
73
+ end
74
+
75
+ context 'time String' do
76
+ let(:input){ '2014-01-01 15:00:00' }
77
+ it { should eq Time.zone.parse('2014-01-01 15:00:00') }
78
+ end
79
+
80
+ context 'natural language String' do
81
+ let(:input){ 'tomorrow at 3:30 pm' }
82
+ it { should eq Time.zone.parse('2014-01-02 15:30:00') }
83
+ end
84
+ end
85
+
86
+ context 'when Chronic is not defined' do
87
+
88
+ before { hide_const('Chronic') }
89
+
90
+ context 'date String' do
91
+ let(:input){ '2014-01-01' }
92
+ it { should eq Time.zone.parse('2014-01-01 00:00:00') }
93
+ end
94
+
95
+ context 'time String' do
96
+ let(:input){ '2014-01-01 15:00:00' }
97
+ it { should eq Time.zone.parse('2014-01-01 15:00:00') }
98
+ end
99
+
100
+ context 'natural language String' do
101
+ let(:input){ 'tomorrow at noon' }
102
+ it { expect{ subject }.to raise_error(ByStar::ParseError, "Cannot parse String #{input.inspect}") }
103
+ end
104
+ end
105
+
106
+ context 'Date' do
107
+ let(:input){ Date.parse('2014-01-01') }
108
+ it { expect eq Time.zone.parse('2014-01-01 00:00:00') }
109
+ end
110
+
111
+ context 'DateTime' do
112
+ let(:input){ Time.zone.parse('2014-01-01 15:00:00').to_datetime }
113
+ it { expect eq Time.zone.parse('2014-01-01 15:00:00') }
114
+ end
115
+
116
+ context 'Time' do
117
+ let(:input){ Time.zone.parse('2014-01-01 15:00:00') }
118
+ it { expect eq Time.zone.parse('2014-01-01 15:00:00') }
119
+ end
120
+ end
121
+
122
+ describe '#week' do
123
+ subject { ByStar::Normalization.week(input, options) }
124
+ it_behaves_like 'date normalization from string'
125
+ it_behaves_like 'date normalization from time value'
126
+
127
+ context 'Integer -1' do
128
+ let(:input){ -1 }
129
+ it { expect{subject}.to raise_error(ByStar::ParseError, 'Week number must be between 0 and 52') }
130
+ end
131
+
132
+ context 'Integer 0' do
133
+ let(:input){ 0 }
134
+ it { expect eq Date.parse('2014-01-01') }
135
+ end
136
+
137
+ context 'Integer 20' do
138
+ let(:input){ 20 }
139
+ it { expect eq Date.parse('2014-05-21') }
140
+ end
141
+
142
+ context 'Integer 53' do
143
+ let(:input){ 53 }
144
+ it { expect{subject}.to raise_error(ByStar::ParseError, 'Week number must be between 0 and 52') }
145
+ end
146
+
147
+ context 'with year option' do
148
+ let(:options){ { year: 2011 } }
149
+
150
+ context 'Integer 0' do
151
+ let(:input){ 0 }
152
+ it { expect eq Date.parse('2011-01-01') }
153
+ end
154
+
155
+ context 'Integer 20' do
156
+ let(:input){ 20 }
157
+ it { expect eq Date.parse('2011-05-21') }
158
+ end
159
+ end
160
+ end
161
+
162
+ describe '#cweek' do
163
+ subject { ByStar::Normalization.cweek(input, options) }
164
+ it_behaves_like 'date normalization from string'
165
+ it_behaves_like 'date normalization from time value'
166
+
167
+ context 'Integer 9' do
168
+ let(:input){ 0 }
169
+ it { expect{subject}.to raise_error(ByStar::ParseError, 'cweek number must be between 1 and 53') }
170
+ end
171
+
172
+ context 'Integer 1' do
173
+ let(:input){ 1 }
174
+ it { expect eq Date.parse('2014-01-01') }
175
+ end
176
+
177
+ context 'Integer 21' do
178
+ let(:input){ 21 }
179
+ it { expect eq Date.parse('2014-05-21') }
180
+ end
181
+
182
+ context 'Integer 54' do
183
+ let(:input){ 54 }
184
+ it { expect{subject}.to raise_error(ByStar::ParseError, 'cweek number must be between 1 and 53') }
185
+ end
186
+
187
+ context 'with year option' do
188
+ let(:options){ { year: 2011 } }
189
+
190
+ context 'Integer 1' do
191
+ let(:input){ 1 }
192
+ it { expect eq Date.parse('2011-01-01') }
193
+ end
194
+
195
+ context 'Integer 21' do
196
+ let(:input){ 21 }
197
+ it { expect eq Date.parse('2011-05-21') }
198
+ end
199
+ end
200
+ end
201
+
202
+ describe '#fortnight' do
203
+ subject { ByStar::Normalization.fortnight(input, options) }
204
+ it_behaves_like 'date normalization from string'
205
+ it_behaves_like 'date normalization from time value'
206
+
207
+ context 'Integer 0' do
208
+ let(:input){ 0 }
209
+ it { expect eq Date.parse('2014-01-01') }
210
+ end
211
+
212
+ context 'Integer 26' do
213
+ let(:input){ 26 }
214
+ it { expect eq Date.parse('2014-12-31') }
215
+ end
216
+
217
+ context 'out of range' do
218
+ specify { expect{ ByStar::Normalization.fortnight(-1) }.to raise_error(ByStar::ParseError, 'Fortnight number must be between 0 and 26') }
219
+ specify { expect{ ByStar::Normalization.fortnight(27) }.to raise_error(ByStar::ParseError, 'Fortnight number must be between 0 and 26') }
220
+ end
221
+
222
+ context 'with year option' do
223
+ let(:options){ { year: 2011 } }
224
+
225
+ context 'Integer 0' do
226
+ let(:input){ 0 }
227
+ it { expect eq Date.parse('2011-01-01') }
228
+ end
229
+
230
+ context 'Integer 26' do
231
+ let(:input){ 26 }
232
+ it { expect eq Date.parse('2011-12-31') }
233
+ end
234
+ end
235
+ end
236
+
237
+ describe '#month' do
238
+ subject { ByStar::Normalization.month(input, options) }
239
+ it_behaves_like 'date normalization from time value'
240
+
241
+ context 'month abbr String' do
242
+ let(:input){ 'Feb' }
243
+ it { expect eq Date.parse('2014-02-01') }
244
+ end
245
+
246
+ context 'month full String' do
247
+ let(:input){ 'February' }
248
+ it { expect eq Date.parse('2014-02-01') }
249
+ end
250
+
251
+ context 'number String' do
252
+ let(:input){ '2' }
253
+ it { expect eq Date.parse('2014-02-01') }
254
+ end
255
+
256
+ context 'Integer' do
257
+ let(:input){ 2 }
258
+ it { expect eq Date.parse('2014-02-01') }
259
+ end
260
+
261
+ context 'out of range' do
262
+ specify { expect{ ByStar::Normalization.month(0) }.to raise_error(ByStar::ParseError, 'Month must be a number between 1 and 12 or a month name') }
263
+ specify { expect{ ByStar::Normalization.month(13) }.to raise_error(ByStar::ParseError, 'Month must be a number between 1 and 12 or a month name') }
264
+ end
265
+
266
+ context 'with year option' do
267
+ let(:options){ { year: 2011 } }
268
+
269
+ context 'month abbr String' do
270
+ let(:input){ 'Dec' }
271
+ it { expect eq Date.parse('2011-12-01') }
272
+ end
273
+
274
+ context 'Integer 12' do
275
+ let(:input){ 10 }
276
+ it { expect eq Date.parse('2011-10-01') }
277
+ end
278
+ end
279
+ end
280
+
281
+ describe '#quarter' do
282
+ subject { ByStar::Normalization.quarter(input, options) }
283
+ it_behaves_like 'date normalization from string'
284
+ it_behaves_like 'date normalization from time value'
285
+
286
+ context 'Integer 1' do
287
+ let(:input){ 1 }
288
+ it { expect eq Date.parse('2014-01-01') }
289
+ end
290
+
291
+ context 'Integer 2' do
292
+ let(:input){ 2 }
293
+ it { expect eq Date.parse('2014-04-01') }
294
+ end
295
+
296
+ context 'Integer 3' do
297
+ let(:input){ 3 }
298
+ it { expect eq Date.parse('2014-07-01') }
299
+ end
300
+
301
+ context 'Integer 4' do
302
+ let(:input){ 4 }
303
+ it { expect eq Date.parse('2014-10-01') }
304
+ end
305
+
306
+ context 'with year option' do
307
+ let(:options){ { year: 2011 } }
308
+
309
+ context 'Integer 3' do
310
+ let(:input){ 3 }
311
+ it { expect eq Date.parse('2011-07-01') }
312
+ end
313
+ end
314
+
315
+ context 'out of range' do
316
+ specify { expect{ ByStar::Normalization.quarter(0) }.to raise_error(ByStar::ParseError, 'Quarter number must be between 1 and 4') }
317
+ specify { expect{ ByStar::Normalization.quarter(5) }.to raise_error(ByStar::ParseError, 'Quarter number must be between 1 and 4') }
318
+ end
319
+ end
320
+
321
+ describe '#year' do
322
+ subject { ByStar::Normalization.year(input, options) }
323
+ it_behaves_like 'date normalization from string'
324
+ it_behaves_like 'date normalization from time value'
325
+
326
+ context 'Integer 69' do
327
+ let(:input){ 69 }
328
+ it { expect eq Date.parse('2069-01-01') }
329
+ end
330
+
331
+ context 'Integer 99' do
332
+ let(:input){ 99 }
333
+ it { expect eq Date.parse('1999-01-01') }
334
+ end
335
+
336
+ context 'Integer 2001' do
337
+ let(:input){ 1 }
338
+ it { expect eq Date.parse('2001-01-01') }
339
+ end
340
+
341
+ context 'String 01' do
342
+ let(:input){ '01' }
343
+ it { expect eq Date.parse('2001-01-01') }
344
+ end
345
+
346
+ context 'String 70' do
347
+ let(:input){ '70' }
348
+ it { expect eq Date.parse('1970-01-01') }
349
+ end
350
+
351
+ context 'String 2001' do
352
+ let(:input){ '2001' }
353
+ it { expect eq Date.parse('2001-01-01') }
354
+ end
355
+ end
356
+
357
+ describe '#time_in_units' do
358
+ subject { ByStar::Normalization.time_in_units(input) }
359
+
360
+ context 'when less than a day' do
361
+ let(:input) { 34876 }
362
+ it { is_expected.to eq(days: 0, hour: 9, min: 41, sec: 16) }
363
+ end
364
+
365
+ context 'when more than a day' do
366
+ let(:input) { 97532 }
367
+ it { is_expected.to eq(days: 1, hour: 3, min: 5, sec: 32) }
368
+ end
369
+ end
370
+
371
+ describe '#apply_offset_start' do
372
+ subject { ByStar::Normalization.apply_offset_start(input, offset) }
373
+ let(:input) { Time.zone.parse('2020-04-05 00:00:00') }
374
+ let(:offset) { 5.hours }
375
+ it { is_expected.to eq Time.zone.parse('2020-04-05 05:00:00') }
376
+ end
377
+
378
+ describe '#apply_offset_end' do
379
+ subject { ByStar::Normalization.apply_offset_end(input, offset) }
380
+ let(:input) { Time.zone.parse('2020-10-04 00:00:00') }
381
+ let(:offset) { 5.hours }
382
+ it { is_expected.to eq Time.zone.parse('2020-10-05 04:59:59') }
383
+ end
384
+ end