by_star 2.2.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +5 -13
  2. data/.gitignore +5 -5
  3. data/.travis.yml +61 -35
  4. data/CHANGELOG.md +44 -35
  5. data/Gemfile +18 -25
  6. data/MIT-LICENSE +20 -20
  7. data/README.md +577 -540
  8. data/Rakefile +18 -18
  9. data/UPGRADING +6 -12
  10. data/by_star.gemspec +34 -32
  11. data/cleaner.rb +24 -24
  12. data/lib/by_star.rb +17 -16
  13. data/lib/by_star/base.rb +68 -70
  14. data/lib/by_star/between.rb +156 -120
  15. data/lib/by_star/directional.rb +37 -33
  16. data/lib/by_star/kernel/date.rb +50 -19
  17. data/lib/by_star/kernel/time.rb +41 -41
  18. data/lib/by_star/normalization.rb +127 -118
  19. data/lib/by_star/orm/active_record/by_star.rb +61 -69
  20. data/lib/by_star/orm/mongoid/by_star.rb +76 -73
  21. data/lib/by_star/orm/mongoid/reorder.rb +23 -0
  22. data/lib/by_star/version.rb +3 -3
  23. data/spec/database.yml +15 -15
  24. data/spec/fixtures/active_record/models.rb +12 -10
  25. data/spec/fixtures/active_record/schema.rb +19 -19
  26. data/spec/fixtures/mongoid/models.rb +31 -29
  27. data/spec/fixtures/shared/seeds.rb +26 -26
  28. data/spec/gemfiles/Gemfile.master +6 -0
  29. data/spec/gemfiles/Gemfile.rails40 +7 -0
  30. data/spec/gemfiles/Gemfile.rails41 +7 -0
  31. data/spec/gemfiles/Gemfile.rails42 +7 -0
  32. data/spec/gemfiles/Gemfile.rails50 +10 -0
  33. data/spec/gemfiles/Gemfile.rails51 +10 -0
  34. data/spec/integration/active_record/active_record_spec.rb +38 -53
  35. data/spec/integration/mongoid/mongoid_spec.rb +37 -46
  36. data/spec/integration/shared/between_times.rb +82 -0
  37. data/spec/integration/shared/by_calendar_month.rb +55 -55
  38. data/spec/integration/shared/by_cweek.rb +54 -0
  39. data/spec/integration/shared/by_day.rb +96 -108
  40. data/spec/integration/shared/by_direction.rb +172 -153
  41. data/spec/integration/shared/by_fortnight.rb +48 -48
  42. data/spec/integration/shared/by_month.rb +50 -50
  43. data/spec/integration/shared/by_quarter.rb +49 -49
  44. data/spec/integration/shared/by_week.rb +54 -54
  45. data/spec/integration/shared/by_weekend.rb +49 -49
  46. data/spec/integration/shared/by_year.rb +48 -48
  47. data/spec/integration/shared/offset_parameter.rb +32 -31
  48. data/spec/integration/shared/order_parameter.rb +36 -0
  49. data/spec/integration/shared/relative.rb +174 -174
  50. data/spec/integration/shared/scope_parameter.rb +73 -72
  51. data/spec/spec_helper.rb +29 -29
  52. data/spec/unit/kernel_date_spec.rb +113 -60
  53. data/spec/unit/kernel_time_spec.rb +57 -57
  54. data/spec/unit/normalization_spec.rb +305 -255
  55. metadata +61 -62
@@ -1,255 +1,305 @@
1
- require 'spec_helper'
2
-
3
- describe ByStar::Normalization do
4
-
5
- let(:options){ {} }
6
-
7
- shared_examples_for 'time 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 Time.zone.parse('2014-01-01 12:00:00') }
14
- end
15
-
16
- context 'time String' do
17
- let(:input){ '2014-01-01 15:00:00' }
18
- it { should eq Time.zone.parse('2014-01-01 15:00:00') }
19
- end
20
-
21
- context 'natural language String' do
22
- let(:input){ 'tomorrow at 3:30 pm' }
23
- it { should eq Time.zone.parse('2014-01-02 15:30:00') }
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 Time.zone.parse('2014-01-01 00:00:00') }
34
- end
35
-
36
- context 'time String' do
37
- let(:input){ '2014-01-01 15:00:00' }
38
- it { should eq Time.zone.parse('2014-01-01 15:00:00') }
39
- end
40
-
41
- context 'natural language String' do
42
- let(:input){ 'tomorrow at noon' }
43
- it { ->{subject}.should raise_error(ByStar::ParseError, "Cannot parse String #{input.inspect}") }
44
- end
45
- end
46
- end
47
-
48
- shared_examples_for 'time normalization from date/time' do
49
- context 'Date' do
50
- let(:input){ Date.parse('2014-01-01') }
51
- it { should eq Time.zone.parse('2014-01-01 00:00:00') }
52
- end
53
-
54
- context 'DateTime' do
55
- let(:input){ Time.zone.parse('2014-01-01 15:00:00').to_datetime }
56
- it { should eq Time.zone.parse('2014-01-01 15:00:00') }
57
- end
58
-
59
- context 'Time' do
60
- let(:input){ Time.zone.parse('2014-01-01 15:00:00') }
61
- it { should eq Time.zone.parse('2014-01-01 15:00:00') }
62
- end
63
- end
64
-
65
- describe '#time' do
66
- subject { ByStar::Normalization.time(input) }
67
- it_behaves_like 'time normalization from string'
68
- it_behaves_like 'time normalization from date/time'
69
- end
70
-
71
- describe '#week' do
72
- subject { ByStar::Normalization.week(input, options) }
73
- it_behaves_like 'time normalization from string'
74
- it_behaves_like 'time normalization from date/time'
75
-
76
- context 'Fixnum 0' do
77
- let(:input){ 0 }
78
- it { should eq Time.zone.parse('2014-01-01 00:00:00') }
79
- end
80
-
81
- context 'Fixnum 20' do
82
- let(:input){ 20 }
83
- it { should eq Time.zone.parse('2014-05-21 00:00:00') }
84
- end
85
-
86
- context 'with year option' do
87
- let(:options){ { :year => 2011 } }
88
-
89
- context 'Fixnum 0' do
90
- let(:input){ 0 }
91
- it { should eq Time.zone.parse('2011-01-01 00:00:00') }
92
- end
93
-
94
- context 'Fixnum 20' do
95
- let(:input){ 20 }
96
- it { should eq Time.zone.parse('2011-05-21 00:00:00') }
97
- end
98
- end
99
- end
100
-
101
- describe '#fortnight' do
102
- subject { ByStar::Normalization.fortnight(input, options) }
103
- it_behaves_like 'time normalization from string'
104
- it_behaves_like 'time normalization from date/time'
105
-
106
- context 'Fixnum 0' do
107
- let(:input){ 0 }
108
- it { should eq Time.zone.parse('2014-01-01 00:00:00') }
109
- end
110
-
111
- context 'Fixnum 26' do
112
- let(:input){ 26 }
113
- it { should eq Time.zone.parse('2014-12-31 00:00:00') }
114
- end
115
-
116
- context 'out of range' do
117
- specify { ->{ ByStar::Normalization.fortnight(-1) }.should raise_error(ByStar::ParseError, 'Fortnight number must be between 0 and 26') }
118
- specify { ->{ ByStar::Normalization.fortnight(27) }.should raise_error(ByStar::ParseError, 'Fortnight number must be between 0 and 26') }
119
- end
120
-
121
- context 'with year option' do
122
- let(:options){ { :year => 2011 } }
123
-
124
- context 'Fixnum 0' do
125
- let(:input){ 0 }
126
- it { should eq Time.zone.parse('2011-01-01 00:00:00') }
127
- end
128
-
129
- context 'Fixnum 26' do
130
- let(:input){ 26 }
131
- it { should eq Time.zone.parse('2011-12-31 00:00:00') }
132
- end
133
- end
134
- end
135
-
136
- describe '#month' do
137
- subject { ByStar::Normalization.month(input, options) }
138
- it_behaves_like 'time normalization from date/time'
139
-
140
- context 'month abbr String' do
141
- let(:input){ 'Feb' }
142
- it { should eq Time.zone.parse('2014-02-01 00:00:00') }
143
- end
144
-
145
- context 'month full String' do
146
- let(:input){ 'February' }
147
- it { should eq Time.zone.parse('2014-02-01 00:00:00') }
148
- end
149
-
150
- context 'number String' do
151
- let(:input){ '2' }
152
- it { should eq Time.zone.parse('2014-02-01 00:00:00') }
153
- end
154
-
155
- context 'Fixnum' do
156
- let(:input){ 2 }
157
- it { should eq Time.zone.parse('2014-02-01 00:00:00') }
158
- end
159
-
160
- context 'out of range' do
161
- specify { ->{ ByStar::Normalization.month(0) }.should raise_error(ByStar::ParseError, 'Month must be a number between 1 and 12 or a month name') }
162
- specify { ->{ ByStar::Normalization.month(13) }.should raise_error(ByStar::ParseError, 'Month must be a number between 1 and 12 or a month name') }
163
- end
164
-
165
- context 'with year option' do
166
- let(:options){ { :year => 2011 } }
167
-
168
- context 'month abbr String' do
169
- let(:input){ 'Dec' }
170
- it { should eq Time.zone.parse('2011-12-01 00:00:00') }
171
- end
172
-
173
- context 'Fixnum 12' do
174
- let(:input){ 10 }
175
- it { should eq Time.zone.parse('2011-10-01 00:00:00') }
176
- end
177
- end
178
- end
179
-
180
- describe '#quarter' do
181
- subject { ByStar::Normalization.quarter(input, options) }
182
- it_behaves_like 'time normalization from string'
183
- it_behaves_like 'time normalization from date/time'
184
-
185
- context 'Fixnum 1' do
186
- let(:input){ 1 }
187
- it { should eq Time.zone.parse('2014-01-01 00:00:00') }
188
- end
189
-
190
- context 'Fixnum 2' do
191
- let(:input){ 2 }
192
- it { should eq Time.zone.parse('2014-04-01 00:00:00') }
193
- end
194
-
195
- context 'Fixnum 3' do
196
- let(:input){ 3 }
197
- it { should eq Time.zone.parse('2014-07-01 00:00:00') }
198
- end
199
-
200
- context 'Fixnum 4' do
201
- let(:input){ 4 }
202
- it { should eq Time.zone.parse('2014-10-01 00:00:00') }
203
- end
204
-
205
- context 'with year option' do
206
- let(:options){ { :year => 2011 } }
207
-
208
- context 'Fixnum 3' do
209
- let(:input){ 3 }
210
- it { should eq Time.zone.parse('2011-07-01 00:00:00') }
211
- end
212
- end
213
-
214
- context 'out of range' do
215
- specify { ->{ ByStar::Normalization.quarter(0) }.should raise_error(ByStar::ParseError, 'Quarter number must be between 1 and 4') }
216
- specify { ->{ ByStar::Normalization.quarter(5) }.should raise_error(ByStar::ParseError, 'Quarter number must be between 1 and 4') }
217
- end
218
- end
219
-
220
- describe '#year' do
221
- subject { ByStar::Normalization.year(input, options) }
222
- it_behaves_like 'time normalization from string'
223
- it_behaves_like 'time normalization from date/time'
224
-
225
- context 'Fixnum 69' do
226
- let(:input){ 69 }
227
- it { should eq Time.zone.parse('2069-01-01 00:00:00') }
228
- end
229
-
230
- context 'Fixnum 99' do
231
- let(:input){ 99 }
232
- it { should eq Time.zone.parse('1999-01-01 00:00:00') }
233
- end
234
-
235
- context 'Fixnum 2001' do
236
- let(:input){ 1 }
237
- it { should eq Time.zone.parse('2001-01-01 00:00:00') }
238
- end
239
-
240
- context 'String 01' do
241
- let(:input){ '01' }
242
- it { should eq Time.zone.parse('2001-01-01 00:00:00') }
243
- end
244
-
245
- context 'String 70' do
246
- let(:input){ '70' }
247
- it { should eq Time.zone.parse('1970-01-01 00:00:00') }
248
- end
249
-
250
- context 'String 2001' do
251
- let(:input){ '2001' }
252
- it { should eq Time.zone.parse('2001-01-01 00:00:00') }
253
- end
254
- end
255
- end
1
+ require 'spec_helper'
2
+
3
+ describe ByStar::Normalization do
4
+
5
+ let(:options){ {} }
6
+
7
+ shared_examples_for 'time 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 Time.zone.parse('2014-01-01 12:00:00') }
14
+ end
15
+
16
+ context 'time String' do
17
+ let(:input){ '2014-01-01 15:00:00' }
18
+ it { should eq Time.zone.parse('2014-01-01 15:00:00') }
19
+ end
20
+
21
+ context 'natural language String' do
22
+ let(:input){ 'tomorrow at 3:30 pm' }
23
+ it { should eq Time.zone.parse('2014-01-02 15:30:00') }
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 Time.zone.parse('2014-01-01 00:00:00') }
34
+ end
35
+
36
+ context 'time String' do
37
+ let(:input){ '2014-01-01 15:00:00' }
38
+ it { should eq Time.zone.parse('2014-01-01 15:00:00') }
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 'time normalization from date/time' do
49
+ context 'Date' do
50
+ let(:input){ Date.parse('2014-01-01') }
51
+ it { expect eq Time.zone.parse('2014-01-01 00:00:00') }
52
+ end
53
+
54
+ context 'DateTime' do
55
+ let(:input){ Time.zone.parse('2014-01-01 15:00:00').to_datetime }
56
+ it { expect eq Time.zone.parse('2014-01-01 15:00:00') }
57
+ end
58
+
59
+ context 'Time' do
60
+ let(:input){ Time.zone.parse('2014-01-01 15:00:00') }
61
+ it { expect eq Time.zone.parse('2014-01-01 15:00:00') }
62
+ end
63
+ end
64
+
65
+ describe '#time' do
66
+ subject { ByStar::Normalization.time(input) }
67
+ it_behaves_like 'time normalization from string'
68
+ it_behaves_like 'time normalization from date/time'
69
+ end
70
+
71
+ describe '#week' do
72
+ subject { ByStar::Normalization.week(input, options) }
73
+ it_behaves_like 'time normalization from string'
74
+ it_behaves_like 'time normalization from date/time'
75
+
76
+ context 'Integer -1' do
77
+ let(:input){ -1 }
78
+ it { expect{subject}.to raise_error(ByStar::ParseError, 'Week number must be between 0 and 52') }
79
+ end
80
+
81
+ context 'Integer 0' do
82
+ let(:input){ 0 }
83
+ it { expect eq Time.zone.parse('2014-01-01 00:00:00') }
84
+ end
85
+
86
+ context 'Integer 20' do
87
+ let(:input){ 20 }
88
+ it { expect eq Time.zone.parse('2014-05-21 00:00:00') }
89
+ end
90
+
91
+ context 'Integer 53' do
92
+ let(:input){ 53 }
93
+ it { expect{subject}.to raise_error(ByStar::ParseError, 'Week number must be between 0 and 52') }
94
+ end
95
+
96
+ context 'with year option' do
97
+ let(:options){ { year: 2011 } }
98
+
99
+ context 'Integer 0' do
100
+ let(:input){ 0 }
101
+ it { expect eq Time.zone.parse('2011-01-01 00:00:00') }
102
+ end
103
+
104
+ context 'Integer 20' do
105
+ let(:input){ 20 }
106
+ it { expect eq Time.zone.parse('2011-05-21 00:00:00') }
107
+ end
108
+ end
109
+ end
110
+
111
+ describe '#cweek' do
112
+ subject { ByStar::Normalization.cweek(input, options) }
113
+ it_behaves_like 'time normalization from string'
114
+ it_behaves_like 'time normalization from date/time'
115
+
116
+ context 'Integer 9' do
117
+ let(:input){ 0 }
118
+ it { expect{subject}.to raise_error(ByStar::ParseError, 'cweek number must be between 1 and 53') }
119
+ end
120
+
121
+ context 'Integer 1' do
122
+ let(:input){ 1 }
123
+ it { expect eq Time.zone.parse('2014-01-01 00:00:00') }
124
+ end
125
+
126
+ context 'Integer 21' do
127
+ let(:input){ 21 }
128
+ it { expect eq Time.zone.parse('2014-05-21 00:00:00') }
129
+ end
130
+
131
+ context 'Integer 54' do
132
+ let(:input){ 54 }
133
+ it { expect{subject}.to raise_error(ByStar::ParseError, 'cweek number must be between 1 and 53') }
134
+ end
135
+
136
+ context 'with year option' do
137
+ let(:options){ { year: 2011 } }
138
+
139
+ context 'Integer 1' do
140
+ let(:input){ 1 }
141
+ it { expect eq Time.zone.parse('2011-01-01 00:00:00') }
142
+ end
143
+
144
+ context 'Integer 21' do
145
+ let(:input){ 21 }
146
+ it { expect eq Time.zone.parse('2011-05-21 00:00:00') }
147
+ end
148
+ end
149
+ end
150
+
151
+ describe '#fortnight' do
152
+ subject { ByStar::Normalization.fortnight(input, options) }
153
+ it_behaves_like 'time normalization from string'
154
+ it_behaves_like 'time normalization from date/time'
155
+
156
+ context 'Integer 0' do
157
+ let(:input){ 0 }
158
+ it { expect eq Time.zone.parse('2014-01-01 00:00:00') }
159
+ end
160
+
161
+ context 'Integer 26' do
162
+ let(:input){ 26 }
163
+ it { expect eq Time.zone.parse('2014-12-31 00:00:00') }
164
+ end
165
+
166
+ context 'out of range' do
167
+ specify { expect{ ByStar::Normalization.fortnight(-1) }.to raise_error(ByStar::ParseError, 'Fortnight number must be between 0 and 26') }
168
+ specify { expect{ ByStar::Normalization.fortnight(27) }.to raise_error(ByStar::ParseError, 'Fortnight number must be between 0 and 26') }
169
+ end
170
+
171
+ context 'with year option' do
172
+ let(:options){ { year: 2011 } }
173
+
174
+ context 'Integer 0' do
175
+ let(:input){ 0 }
176
+ it { expect eq Time.zone.parse('2011-01-01 00:00:00') }
177
+ end
178
+
179
+ context 'Integer 26' do
180
+ let(:input){ 26 }
181
+ it { expect eq Time.zone.parse('2011-12-31 00:00:00') }
182
+ end
183
+ end
184
+ end
185
+
186
+ describe '#month' do
187
+ subject { ByStar::Normalization.month(input, options) }
188
+ it_behaves_like 'time normalization from date/time'
189
+
190
+ context 'month abbr String' do
191
+ let(:input){ 'Feb' }
192
+ it { expect eq Time.zone.parse('2014-02-01 00:00:00') }
193
+ end
194
+
195
+ context 'month full String' do
196
+ let(:input){ 'February' }
197
+ it { expect eq Time.zone.parse('2014-02-01 00:00:00') }
198
+ end
199
+
200
+ context 'number String' do
201
+ let(:input){ '2' }
202
+ it { expect eq Time.zone.parse('2014-02-01 00:00:00') }
203
+ end
204
+
205
+ context 'Integer' do
206
+ let(:input){ 2 }
207
+ it { expect eq Time.zone.parse('2014-02-01 00:00:00') }
208
+ end
209
+
210
+ context 'out of range' do
211
+ specify { expect{ ByStar::Normalization.month(0) }.to raise_error(ByStar::ParseError, 'Month must be a number between 1 and 12 or a month name') }
212
+ specify { expect{ ByStar::Normalization.month(13) }.to raise_error(ByStar::ParseError, 'Month must be a number between 1 and 12 or a month name') }
213
+ end
214
+
215
+ context 'with year option' do
216
+ let(:options){ { year: 2011 } }
217
+
218
+ context 'month abbr String' do
219
+ let(:input){ 'Dec' }
220
+ it { expect eq Time.zone.parse('2011-12-01 00:00:00') }
221
+ end
222
+
223
+ context 'Integer 12' do
224
+ let(:input){ 10 }
225
+ it { expect eq Time.zone.parse('2011-10-01 00:00:00') }
226
+ end
227
+ end
228
+ end
229
+
230
+ describe '#quarter' do
231
+ subject { ByStar::Normalization.quarter(input, options) }
232
+ it_behaves_like 'time normalization from string'
233
+ it_behaves_like 'time normalization from date/time'
234
+
235
+ context 'Integer 1' do
236
+ let(:input){ 1 }
237
+ it { expect eq Time.zone.parse('2014-01-01 00:00:00') }
238
+ end
239
+
240
+ context 'Integer 2' do
241
+ let(:input){ 2 }
242
+ it { expect eq Time.zone.parse('2014-04-01 00:00:00') }
243
+ end
244
+
245
+ context 'Integer 3' do
246
+ let(:input){ 3 }
247
+ it { expect eq Time.zone.parse('2014-07-01 00:00:00') }
248
+ end
249
+
250
+ context 'Integer 4' do
251
+ let(:input){ 4 }
252
+ it { expect eq Time.zone.parse('2014-10-01 00:00:00') }
253
+ end
254
+
255
+ context 'with year option' do
256
+ let(:options){ { year: 2011 } }
257
+
258
+ context 'Integer 3' do
259
+ let(:input){ 3 }
260
+ it { expect eq Time.zone.parse('2011-07-01 00:00:00') }
261
+ end
262
+ end
263
+
264
+ context 'out of range' do
265
+ specify { expect{ ByStar::Normalization.quarter(0) }.to raise_error(ByStar::ParseError, 'Quarter number must be between 1 and 4') }
266
+ specify { expect{ ByStar::Normalization.quarter(5) }.to raise_error(ByStar::ParseError, 'Quarter number must be between 1 and 4') }
267
+ end
268
+ end
269
+
270
+ describe '#year' do
271
+ subject { ByStar::Normalization.year(input, options) }
272
+ it_behaves_like 'time normalization from string'
273
+ it_behaves_like 'time normalization from date/time'
274
+
275
+ context 'Integer 69' do
276
+ let(:input){ 69 }
277
+ it { expect eq Time.zone.parse('2069-01-01 00:00:00') }
278
+ end
279
+
280
+ context 'Integer 99' do
281
+ let(:input){ 99 }
282
+ it { expect eq Time.zone.parse('1999-01-01 00:00:00') }
283
+ end
284
+
285
+ context 'Integer 2001' do
286
+ let(:input){ 1 }
287
+ it { expect eq Time.zone.parse('2001-01-01 00:00:00') }
288
+ end
289
+
290
+ context 'String 01' do
291
+ let(:input){ '01' }
292
+ it { expect eq Time.zone.parse('2001-01-01 00:00:00') }
293
+ end
294
+
295
+ context 'String 70' do
296
+ let(:input){ '70' }
297
+ it { expect eq Time.zone.parse('1970-01-01 00:00:00') }
298
+ end
299
+
300
+ context 'String 2001' do
301
+ let(:input){ '2001' }
302
+ it { expect eq Time.zone.parse('2001-01-01 00:00:00') }
303
+ end
304
+ end
305
+ end