by_star 2.2.1 → 3.0.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.
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,72 +1,73 @@
1
- require 'spec_helper'
2
-
3
- shared_examples_for 'scope parameter' do
4
-
5
- describe 'scope' do
6
- it 'should memoize the scope variable' do
7
- Event.instance_variable_get(:@by_star_scope).should be_nil
8
- Post.instance_variable_get(:@by_star_scope).should be_nil
9
- Appointment.instance_variable_get(:@by_star_scope).should be_a Proc
10
- end
11
-
12
- context 'between_times with default scope' do
13
- subject { Appointment.between_times(Date.parse('2013-12-01'), Date.parse('2014-02-01')) }
14
- its(:count) { should eq 3 }
15
- end
16
-
17
- context 'between_times with scope override as a query criteria' do
18
- subject { Appointment.between_times(Date.parse('2013-12-01'), Date.parse('2014-02-01'), scope: Appointment.unscoped) }
19
- its(:count) { should eq 14 }
20
- end
21
-
22
- context 'between_times with scope override as a Lambda' do
23
- subject { Appointment.between_times(Date.parse('2013-12-01'), Date.parse('2014-02-01'), scope: ->{ unscoped }) }
24
- its(:count) { should eq 14 }
25
- end
26
-
27
- context 'between_times with scope override as a Lambda' do
28
- subject { Appointment.between_times(Date.parse('2013-12-01'), Date.parse('2014-02-01'), scope: ->(x){ unscoped }) }
29
- it{ ->{subject}.should raise_error }
30
- end
31
-
32
- context 'between_times with scope override as a Proc with arguments' do
33
- subject { Appointment.between_times(Date.parse('2013-12-01'), Date.parse('2014-02-01'), scope: Proc.new{ unscoped }) }
34
- its(:count) { should eq 14 }
35
- end
36
-
37
- context 'between_times with scope override as a Proc with arguments' do
38
- subject { Appointment.between_times(Date.parse('2013-12-01'), Date.parse('2014-02-01'), scope: Proc.new{|x,y| unscoped }) }
39
- it{ ->{subject}.should raise_error }
40
- end
41
-
42
- context 'by_month with default scope' do
43
- subject { Appointment.by_month(Date.parse('2014-01-01')) }
44
- its(:count) { should eq 2 }
45
- end
46
-
47
- context 'by_month with scope override as a query criteria' do
48
- subject { Appointment.by_month(Date.parse('2014-01-01'), scope: Appointment.unscoped) }
49
- its(:count) { should eq 6 }
50
- end
51
-
52
- context 'by_month with scope override as a Lambda' do
53
- subject { Appointment.by_month(Date.parse('2014-01-01'), scope: ->{ unscoped }) }
54
- its(:count) { should eq 6 }
55
- end
56
-
57
- context 'by_month with scope override as a Lambda with arguments' do
58
- subject { Appointment.by_month(Date.parse('2014-01-01'), scope: ->(x){ unscoped }) }
59
- it{ ->{subject}.should raise_error }
60
- end
61
-
62
- context 'by_month with scope override as a Proc' do
63
- subject { Appointment.by_month(Date.parse('2014-01-01'), scope: Proc.new{ unscoped }) }
64
- its(:count) { should eq 6 }
65
- end
66
-
67
- context 'by_month with scope override as a Proc with arguments' do
68
- subject { Appointment.by_month(Date.parse('2014-01-01'), scope: Proc.new{|x| unscoped }) }
69
- it{ ->{subject}.should raise_error }
70
- end
71
- end
72
- end
1
+ require 'spec_helper'
2
+
3
+ shared_examples_for 'scope parameter' do
4
+
5
+ describe ':scope' do
6
+
7
+ it 'should memoize the scope variable' do
8
+ expect(Event.instance_variable_get(:@by_star_scope)).to be_nil
9
+ expect(Post.instance_variable_get(:@by_star_scope)).to be_nil
10
+ expect(Appointment.instance_variable_get(:@by_star_scope)).to be_a Proc
11
+ end
12
+
13
+ context 'between_times with default scope' do
14
+ subject { Appointment.between_times(Date.parse('2013-12-01'), Date.parse('2014-02-01')) }
15
+ it { expect(subject.count).to eql(3) }
16
+ end
17
+
18
+ context 'between_times with scope override as a query criteria' do
19
+ subject { Appointment.between_times(Date.parse('2013-12-01')..Date.parse('2014-02-01'), scope: Appointment.unscoped) }
20
+ it { expect(subject.count).to eql(14) }
21
+ end
22
+
23
+ context 'between_times with scope override as a Lambda' do
24
+ subject { Appointment.between_times([Date.parse('2013-12-01'), Date.parse('2014-02-01')], scope: ->{ unscoped }) }
25
+ it { expect(subject.count).to eql(14) }
26
+ end
27
+
28
+ context 'between_times with scope override as a Lambda' do
29
+ subject { Appointment.between_times(Date.parse('2013-12-01')..Date.parse('2014-02-01'), scope: ->(x){ unscoped }) }
30
+ it{ expect{ subject }.to raise_error(RuntimeError, 'ByStar :scope Proc requires :scope_args to be specified.') }
31
+ end
32
+
33
+ context 'between_times with scope override as a Proc with arguments' do
34
+ subject { Appointment.between_times(Date.parse('2013-12-01'), Date.parse('2014-02-01'), scope: Proc.new{ unscoped }) }
35
+ it { expect(subject.count).to eql(14) }
36
+ end
37
+
38
+ context 'between_times with scope override as a Proc with arguments' do
39
+ subject { Appointment.between_times([Date.parse('2013-12-01'), Date.parse('2014-02-01')], scope: Proc.new{|x,y| unscoped }) }
40
+ it{ expect{ subject }.to raise_error(RuntimeError, 'ByStar :scope Proc requires :scope_args to be specified.') }
41
+ end
42
+
43
+ context 'by_month with default scope' do
44
+ subject { Appointment.by_month(Date.parse('2014-01-01')) }
45
+ it { expect(subject.count).to eql(2) }
46
+ end
47
+
48
+ context 'by_month with scope override as a query criteria' do
49
+ subject { Appointment.by_month(Date.parse('2014-01-01'), scope: Appointment.unscoped) }
50
+ it { expect(subject.count).to eql(6) }
51
+ end
52
+
53
+ context 'by_month with scope override as a Lambda' do
54
+ subject { Appointment.by_month(Date.parse('2014-01-01'), scope: ->{ unscoped }) }
55
+ it { expect(subject.count).to eql(6) }
56
+ end
57
+
58
+ context 'by_month with scope override as a Lambda with arguments' do
59
+ subject { Appointment.by_month(Date.parse('2014-01-01'), scope: ->(x){ unscoped }) }
60
+ it{ expect{ subject }.to raise_error(RuntimeError, 'ByStar :scope Proc requires :scope_args to be specified.') }
61
+ end
62
+
63
+ context 'by_month with scope override as a Proc' do
64
+ subject { Appointment.by_month(Date.parse('2014-01-01'), scope: Proc.new{ unscoped }) }
65
+ it { expect(subject.count).to eql(6) }
66
+ end
67
+
68
+ context 'by_month with scope override as a Proc with arguments' do
69
+ subject { Appointment.by_month(Date.parse('2014-01-01'), scope: Proc.new{|x| unscoped }) }
70
+ it{ expect{ subject }.to raise_error(RuntimeError, 'ByStar :scope Proc requires :scope_args to be specified.') }
71
+ end
72
+ end
73
+ end
@@ -1,29 +1,29 @@
1
- require 'rubygems'
2
- require 'bundler'
3
- Bundler.setup
4
- require 'fileutils'
5
- require 'logger'
6
-
7
- FileUtils.mkdir_p(File.dirname(__FILE__) + "/tmp")
8
- $:.unshift(File.join(File.dirname(__FILE__), "../lib"))
9
-
10
- require 'active_record'
11
- require 'mongoid'
12
- require 'chronic'
13
- require 'timecop'
14
- require 'by_star'
15
-
16
- # Specs should pass regardless of timezone
17
- Time.zone = %w(Asia/Tokyo America/New_York Australia/Sydney UTC).sample
18
- puts "Running specs in #{Time.zone} timezone..."
19
-
20
- # Set Rails time to 2014-01-01 00:00:00
21
- Timecop.travel(Time.zone.local(2014))
22
-
23
- def testing_mongoid?
24
- ENV['DB'] == 'mongodb' || ENV['DB'].nil?
25
- end
26
-
27
- def testing_active_record?
28
- ENV['DB'] != 'mongodb'
29
- end
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.setup
4
+ require 'fileutils'
5
+ require 'logger'
6
+
7
+ FileUtils.mkdir_p(File.dirname(__FILE__) + "/tmp")
8
+ $:.unshift(File.join(File.dirname(__FILE__), "../lib"))
9
+
10
+ require 'active_record'
11
+ require 'mongoid'
12
+ require 'chronic'
13
+ require 'timecop'
14
+ require 'by_star'
15
+
16
+ # Specs should pass regardless of timezone
17
+ Time.zone = %w(Asia/Tokyo America/New_York Australia/Sydney UTC).sample
18
+ puts "Running specs in #{Time.zone} timezone..."
19
+
20
+ # Set Rails time to 2014-01-01 00:00:00
21
+ Timecop.travel(Time.zone.local(2014))
22
+
23
+ def testing_mongoid?
24
+ ENV['DB'] == 'mongodb'
25
+ end
26
+
27
+ def testing_active_record?
28
+ !testing_mongoid?
29
+ end
@@ -1,60 +1,113 @@
1
- require 'spec_helper'
2
-
3
- describe Date do
4
-
5
- describe '#in_time_zone' do
6
-
7
- subject { Date.new }
8
-
9
- before do
10
- stub_const('Date', Class.new)
11
- Date.any_instance.stub(:to_time_in_current_zone)
12
- end
13
-
14
- context 'when #in_time_zone is already defined' do
15
- before do
16
- Date.any_instance.should_receive(:in_time_zone)
17
- end
18
-
19
- context 'when ByStar::Kernel::Date included' do
20
- before do
21
- ::Date.__send__(:include, ByStar::Kernel::Date)
22
- end
23
-
24
- it 'should not be aliased to #to_time_in_current_zone' do
25
- subject.should_not_receive(:to_time_in_current_zone)
26
- subject.in_time_zone
27
- end
28
- end
29
-
30
- context 'when ByStar::Kernel::Date not included' do
31
-
32
- it 'should not be aliased to #to_time_in_current_zone' do
33
- subject.should_not_receive(:to_time_in_current_zone)
34
- subject.in_time_zone
35
- end
36
- end
37
- end
38
-
39
- context 'when #in_time_zone is not defined' do
40
-
41
- context 'when ByStar::Kernel::Date included' do
42
- before do
43
- ::Date.__send__(:include, ByStar::Kernel::Date)
44
- end
45
-
46
- it 'should be aliased to #to_time_in_current_zone' do
47
- subject.should_receive(:to_time_in_current_zone)
48
- subject.in_time_zone
49
- end
50
- end
51
-
52
- context 'when ByStar::Kernel::Date not included' do
53
-
54
- it 'should raise NoMethodError' do
55
- ->{ subject.in_time_zone }.should raise_error(NoMethodError)
56
- end
57
- end
58
- end
59
- end
60
- end
1
+ require 'spec_helper'
2
+
3
+ describe Date do
4
+
5
+ describe '#in_time_zone' do
6
+
7
+ subject { Date.new }
8
+
9
+ before do
10
+ stub_const('Date', Class.new)
11
+ allow_any_instance_of(Date).to receive(:to_time_in_current_zone)
12
+ end
13
+
14
+ context 'when #in_time_zone is already defined' do
15
+ before do
16
+ expect_any_instance_of(Date).to receive(:in_time_zone)
17
+ end
18
+
19
+ context 'when ByStar::Kernel::Date included' do
20
+ before do
21
+ ::Date.__send__(:include, ByStar::Kernel::Date)
22
+ end
23
+
24
+ it 'should not be aliased to #to_time_in_current_zone' do
25
+ expect(subject).not_to receive(:to_time_in_current_zone)
26
+ subject.in_time_zone
27
+ end
28
+ end
29
+
30
+ context 'when ByStar::Kernel::Date not included' do
31
+
32
+ it 'should not be aliased to #to_time_in_current_zone' do
33
+ expect(subject).not_to receive(:to_time_in_current_zone)
34
+ subject.in_time_zone
35
+ end
36
+ end
37
+ end
38
+
39
+ context 'when #in_time_zone is not defined' do
40
+
41
+ context 'when ByStar::Kernel::Date included' do
42
+ before do
43
+ ::Date.__send__(:include, ByStar::Kernel::Date)
44
+ end
45
+
46
+ it 'should be aliased to #to_time_in_current_zone' do
47
+ expect(subject).to receive(:to_time_in_current_zone)
48
+ subject.in_time_zone
49
+ end
50
+ end
51
+
52
+ context 'when ByStar::Kernel::Date not included' do
53
+
54
+ it 'should raise NoMethodError' do
55
+ expect{ subject.in_time_zone }.to raise_error(NoMethodError)
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ describe 'weekend' do
62
+
63
+ (0..6).each do |n|
64
+ context "Monday plus #{n} days" do
65
+ subject { Date.parse('2014-01-06') + n.days }
66
+ it { expect(subject.beginning_of_weekend).to eq Date.parse('2014-01-11') }
67
+ it { expect(subject.end_of_weekend).to eq Date.parse('2014-01-12') }
68
+ end
69
+ end
70
+ end
71
+
72
+ describe 'fortnight' do
73
+
74
+ context 'first day of year' do
75
+ subject { Date.parse '2014-01-01' }
76
+ it { expect(subject.beginning_of_fortnight).to eq Date.parse('2014-01-01') }
77
+ it { expect(subject.end_of_fortnight).to eq Date.parse('2014-01-14') }
78
+ end
79
+
80
+ context 'second fortnight of year' do
81
+ subject { Date.parse '2014-01-16' }
82
+ it { expect(subject.beginning_of_fortnight).to eq Date.parse('2014-01-15') }
83
+ it { expect(subject.end_of_fortnight).to eq Date.parse('2014-01-28') }
84
+ end
85
+
86
+ context 'middle of year' do
87
+ subject { Date.parse '2014-06-13' }
88
+ it { expect(subject.beginning_of_fortnight).to eq Date.parse('2014-06-04') }
89
+ it { expect(subject.end_of_fortnight).to eq Date.parse('2014-06-17') }
90
+ end
91
+
92
+ context 'last day of year' do
93
+ subject { Date.parse '2014-12-31' }
94
+ it { expect(subject.beginning_of_fortnight).to eq Date.parse('2014-12-31') }
95
+ it { expect(subject.end_of_fortnight).to eq Date.parse('2015-01-13') }
96
+ end
97
+ end
98
+
99
+ describe 'calendar_month' do
100
+
101
+ subject { Date.parse '2014-01-01' }
102
+
103
+ context 'week begins Monday' do
104
+ it { expect(subject.beginning_of_calendar_month).to eq Date.parse('2013-12-30') }
105
+ it { expect(subject.end_of_calendar_month).to eq Date.parse('2014-02-02') }
106
+ end
107
+
108
+ context 'week begins Sunday' do
109
+ it { expect(subject.beginning_of_calendar_month(:sunday)).to eq Date.parse('2013-12-29') }
110
+ it { expect(subject.end_of_calendar_month(:sunday)).to eq Date.parse('2014-02-01') }
111
+ end
112
+ end
113
+ end
@@ -1,57 +1,57 @@
1
- require 'spec_helper'
2
-
3
- describe Time do
4
-
5
- describe 'weekend' do
6
-
7
- (0..6).each do |n|
8
- context "Monday plus #{n} days" do
9
- subject { Time.zone.parse('2014-01-06') + n.days }
10
- its(:beginning_of_weekend){ should eq Time.zone.parse('2014-01-10 15:00') }
11
- its(:end_of_weekend){ should eq Time.zone.parse('2014-01-13 02:00').end_of_hour }
12
- end
13
- end
14
- end
15
-
16
- describe 'fortnight' do
17
-
18
- context 'first day of year' do
19
- subject { Time.zone.parse '2014-01-01' }
20
- its(:beginning_of_fortnight){ should eq Time.zone.parse('2014-01-01') }
21
- its(:end_of_fortnight){ should eq Time.zone.parse('2014-01-14').end_of_day }
22
- end
23
-
24
- context 'second fortnight of year' do
25
- subject { Time.zone.parse '2014-01-16' }
26
- its(:beginning_of_fortnight){ should eq Time.zone.parse('2014-01-15') }
27
- its(:end_of_fortnight){ should eq Time.zone.parse('2014-01-28').end_of_day }
28
- end
29
-
30
- context 'middle of year' do
31
- subject { Time.zone.parse '2014-06-13' }
32
- its(:beginning_of_fortnight){ should eq Time.zone.parse('2014-06-04') }
33
- its(:end_of_fortnight){ should eq Time.zone.parse('2014-06-17').end_of_day }
34
- end
35
-
36
- context 'last day of year' do
37
- subject { Time.zone.parse '2014-12-31' }
38
- its(:beginning_of_fortnight){ should eq Time.zone.parse('2014-12-31') }
39
- its(:end_of_fortnight){ should eq Time.zone.parse('2015-01-13').end_of_day }
40
- end
41
- end
42
-
43
- describe 'calendar_month' do
44
-
45
- subject { Time.zone.parse '2014-01-01' }
46
-
47
- context 'week begins Monday' do
48
- its(:beginning_of_calendar_month){ should eq Time.zone.parse('2013-12-30') }
49
- its(:end_of_calendar_month){ should eq Time.zone.parse('2014-02-02').end_of_day }
50
- end
51
-
52
- context 'week begins Sunday' do
53
- it { subject.beginning_of_calendar_month(:sunday).should eq Time.zone.parse('2013-12-29') }
54
- it { subject.end_of_calendar_month(:sunday).should eq Time.zone.parse('2014-02-01').end_of_day }
55
- end
56
- end
57
- end
1
+ require 'spec_helper'
2
+
3
+ describe Time do
4
+
5
+ describe 'weekend' do
6
+
7
+ (0..6).each do |n|
8
+ context "Monday plus #{n} days" do
9
+ subject { Time.zone.parse('2014-01-06') + n.days }
10
+ it { expect(subject.beginning_of_weekend).to eq Time.zone.parse('2014-01-11') }
11
+ it { expect(subject.end_of_weekend).to eq Time.zone.parse('2014-01-12').end_of_day }
12
+ end
13
+ end
14
+ end
15
+
16
+ describe 'fortnight' do
17
+
18
+ context 'first day of year' do
19
+ subject { Time.zone.parse '2014-01-01' }
20
+ it { expect(subject.beginning_of_fortnight).to eq Time.zone.parse('2014-01-01') }
21
+ it { expect(subject.end_of_fortnight).to eq Time.zone.parse('2014-01-14').end_of_day }
22
+ end
23
+
24
+ context 'second fortnight of year' do
25
+ subject { Time.zone.parse '2014-01-16' }
26
+ it { expect(subject.beginning_of_fortnight).to eq Time.zone.parse('2014-01-15') }
27
+ it { expect(subject.end_of_fortnight).to eq Time.zone.parse('2014-01-28').end_of_day }
28
+ end
29
+
30
+ context 'middle of year' do
31
+ subject { Time.zone.parse '2014-06-13' }
32
+ it { expect(subject.beginning_of_fortnight).to eq Time.zone.parse('2014-06-04') }
33
+ it { expect(subject.end_of_fortnight).to eq Time.zone.parse('2014-06-17').end_of_day }
34
+ end
35
+
36
+ context 'last day of year' do
37
+ subject { Time.zone.parse '2014-12-31' }
38
+ it { expect(subject.beginning_of_fortnight).to eq Time.zone.parse('2014-12-31') }
39
+ it { expect(subject.end_of_fortnight).to eq Time.zone.parse('2015-01-13').end_of_day }
40
+ end
41
+ end
42
+
43
+ describe 'calendar_month' do
44
+
45
+ subject { Time.zone.parse '2014-01-01' }
46
+
47
+ context 'week begins Monday' do
48
+ it { expect(subject.beginning_of_calendar_month).to eq Time.zone.parse('2013-12-30') }
49
+ it { expect(subject.end_of_calendar_month).to eq Time.zone.parse('2014-02-02').end_of_day }
50
+ end
51
+
52
+ context 'week begins Sunday' do
53
+ it { expect(subject.beginning_of_calendar_month(:sunday)).to eq Time.zone.parse('2013-12-29') }
54
+ it { expect(subject.end_of_calendar_month(:sunday)).to eq Time.zone.parse('2014-02-01').end_of_day }
55
+ end
56
+ end
57
+ end