by_star 2.2.0.rc1 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/UPGRADING CHANGED
@@ -1,9 +1,11 @@
1
1
  Upgrading to ByStar 2.2.0
2
2
  -------------------------
3
3
 
4
- * For Mongoid only, ByStar's `.between` method has been removed and replaced with `.between_times`
5
- (previously `.between_times` was an alias to `.between`). Mongoid already provides a native `.between`
6
- finder method that we do not want to mask. ActiveRecord users may continue to use either method.
4
+ * ActiveRecord: the `between` method has been deprecated as of version 2.2.0, and will be removed in version 3.3.0.
5
+ Please use `between_times` instead.
6
+
7
+ * Mongoid: the `between` method has been removed as of version 2.2.0, as it conflicts with the native Mongoid `between`
8
+ method. Please use `between_times` instead.
7
9
 
8
10
  * Chronic gem (used for time string parsing) has been removed as a hard dependency for ByStar,
9
11
  however it is still supported. If you would like to use Chronic with ByStar, please explicitly
@@ -5,10 +5,12 @@ module ByStar
5
5
  include ByStar::Between
6
6
  include ByStar::Directional
7
7
 
8
- def by_star_field(start_field = nil, end_field = nil, options = {})
9
- @by_star_start_field ||= start_field
10
- @by_star_end_field ||= end_field
8
+ def by_star_field(*args)
9
+ options = args.extract_options!
10
+ @by_star_start_field ||= args[0]
11
+ @by_star_end_field ||= args[1]
11
12
  @by_star_offset ||= options[:offset]
13
+ @by_star_scope ||= options[:scope]
12
14
  end
13
15
 
14
16
  def by_star_offset(options = {})
@@ -31,6 +33,19 @@ module ByStar
31
33
  field.to_s
32
34
  end
33
35
 
36
+ def by_star_scope(options={})
37
+ scope = options[:scope] || @by_star_scope || self
38
+ if scope.is_a?(Proc)
39
+ if scope.arity == 0
40
+ return instance_exec(&scope)
41
+ else
42
+ return instance_exec(self, &scope)
43
+ end
44
+ else
45
+ return scope
46
+ end
47
+ end
48
+
34
49
  protected
35
50
 
36
51
  # Wrapper function which extracts time and options for each by_star query.
@@ -14,18 +14,6 @@ module ByStar
14
14
  end
15
15
  end
16
16
 
17
- def today(options={})
18
- by_day(Time.zone.now, options)
19
- end
20
-
21
- def yesterday(options={})
22
- by_day(Time.zone.now.yesterday, options)
23
- end
24
-
25
- def tomorrow(options={})
26
- by_day(Time.zone.now.tomorrow, options)
27
- end
28
-
29
17
  def by_week(*args)
30
18
  with_by_star_options(*args) do |time, options|
31
19
  time = ByStar::Normalization.week(time, options)
@@ -76,5 +64,57 @@ module ByStar
76
64
  between_times(time.beginning_of_year, time.end_of_year, options)
77
65
  end
78
66
  end
67
+
68
+ def today(options={})
69
+ by_day(Time.zone.now, options)
70
+ end
71
+
72
+ def yesterday(options={})
73
+ by_day(Time.zone.now.yesterday, options)
74
+ end
75
+
76
+ def tomorrow(options={})
77
+ by_day(Time.zone.now.tomorrow, options)
78
+ end
79
+
80
+ def past_day(options={})
81
+ between_times(Time.zone.now - 1.day, Time.zone.now, options)
82
+ end
83
+
84
+ def past_week(options={})
85
+ between_times(Time.zone.now - 1.week, Time.zone.now, options)
86
+ end
87
+
88
+ def past_fortnight(options={})
89
+ between_times(Time.zone.now - 2.weeks, Time.zone.now, options)
90
+ end
91
+
92
+ def past_month(options={})
93
+ between_times(Time.zone.now - 1.month, Time.zone.now, options)
94
+ end
95
+
96
+ def past_year(options={})
97
+ between_times(Time.zone.now - 1.year, Time.zone.now, options)
98
+ end
99
+
100
+ def next_day(options={})
101
+ between_times(Time.zone.now, Time.zone.now + 1.day, options)
102
+ end
103
+
104
+ def next_week(options={})
105
+ between_times(Time.zone.now, Time.zone.now + 1.week, options)
106
+ end
107
+
108
+ def next_fortnight(options={})
109
+ between_times(Time.zone.now, Time.zone.now + 2.weeks, options)
110
+ end
111
+
112
+ def next_month(options={})
113
+ between_times(Time.zone.now, Time.zone.now + 1.month, options)
114
+ end
115
+
116
+ def next_year(options={})
117
+ between_times(Time.zone.now, Time.zone.now + 1.year, options)
118
+ end
79
119
  end
80
120
  end
@@ -18,14 +18,14 @@ module ByStar
18
18
  # A "Fortnight" is defined as a two week period, with the first fortnight of the
19
19
  # year beginning on 1st January.
20
20
  def beginning_of_fortnight
21
- beginning_of_year + ((self - beginning_of_year) / 2.weeks).to_i * 2.weeks
21
+ (beginning_of_year.to_date + 14 * ((self - beginning_of_year) / 2.weeks).to_i).beginning_of_day
22
22
  end
23
23
 
24
24
  def end_of_fortnight
25
- (beginning_of_fortnight + 13.days).end_of_day
25
+ (beginning_of_fortnight.to_date + 13).end_of_day
26
26
  end
27
27
 
28
- # A "Calendar Month" is defined as a month as it appears on a calendar, including days
28
+ # A "Calendar Month" is defined as a month as it appears on a calendar, including days form
29
29
  # previous/following months which are part of the first/last weeks of the given month.
30
30
  def beginning_of_calendar_month(*args)
31
31
  beginning_of_month.beginning_of_week(*args)
@@ -9,16 +9,23 @@ module ByStar
9
9
  #
10
10
  # Currently only supports Time objects.
11
11
  def between_times_query(start, finish, options={})
12
- scope = if options[:strict] || by_star_start_field == by_star_end_field
13
- where("#{by_star_start_field} >= ? AND #{by_star_end_field} <= ?", start, finish)
12
+ start_field = by_star_start_field(options)
13
+ end_field = by_star_end_field(options)
14
+
15
+ scope = by_star_scope(options)
16
+ scope = if options[:strict] || start_field == end_field
17
+ scope.where("#{start_field} >= ? AND #{end_field} <= ?", start, finish)
14
18
  else
15
- where("#{by_star_end_field} > ? AND #{by_star_start_field} < ?", start, finish)
19
+ scope.where("#{end_field} > ? AND #{start_field} < ?", start, finish)
16
20
  end
17
21
  scope = scope.order(options[:order]) if options[:order]
18
22
  scope
19
23
  end
20
24
 
21
- alias_method :between, :between_times
25
+ def between(*args)
26
+ ActiveSupport::Deprecation.warn 'ByStar `between` method will be removed in v3.0.0. Please use `between_times`'
27
+ between_times(*args)
28
+ end
22
29
 
23
30
  protected
24
31
 
@@ -27,26 +34,26 @@ module ByStar
27
34
  end
28
35
 
29
36
  def before_query(time, options={})
30
- field = by_star_start_field
31
- where("#{field} <= ?", time)
37
+ field = by_star_start_field(options)
38
+ by_star_scope(options).where("#{field} <= ?", time)
32
39
  end
33
40
 
34
41
  def after_query(time, options={})
35
- field = by_star_start_field
36
- where("#{field} >= ?", time)
42
+ field = by_star_start_field(options)
43
+ by_star_scope(options).where("#{field} >= ?", time)
37
44
  end
38
45
  end
39
46
 
40
47
  def previous(options={})
41
48
  field = self.class.by_star_start_field
42
49
  value = self.send(field.split(".").last)
43
- self.class.where("#{field} < ?", value).reorder("#{field} DESC").first
50
+ self.class.by_star_scope(options).where("#{field} < ?", value).reorder("#{field} DESC").first
44
51
  end
45
52
 
46
53
  def next(options={})
47
54
  field = self.class.by_star_start_field
48
55
  value = self.send(field.split(".").last)
49
- self.class.where("#{field} > ?", value).reorder("#{field} ASC").first
56
+ self.class.by_star_scope(options).where("#{field} > ?", value).reorder("#{field} ASC").first
50
57
  end
51
58
  end
52
59
  end
@@ -10,10 +10,14 @@ module Mongoid
10
10
  include ::ByStar::Base
11
11
 
12
12
  def between_times_query(start, finish, options={})
13
- scope = if options[:strict] || by_star_start_field == by_star_end_field
14
- gte(by_star_start_field => start).lte(by_star_end_field => finish)
13
+ start_field = by_star_start_field(options)
14
+ end_field = by_star_end_field(options)
15
+
16
+ scope = by_star_scope(options)
17
+ scope = if options[:strict] || start_field == end_field
18
+ scope.gte(start_field => start).lte(end_field => finish)
15
19
  else
16
- gt(by_star_end_field => start).lt(by_star_start_field => finish)
20
+ scope.gt(end_field => start).lt(start_field => finish)
17
21
  end
18
22
  scope = scope.order_by(field => options[:order]) if options[:order]
19
23
  scope
@@ -36,24 +40,24 @@ module Mongoid
36
40
  end
37
41
 
38
42
  def before_query(time, options={})
39
- field = by_star_start_field
40
- lte(field => time)
43
+ field = by_star_start_field(options)
44
+ by_star_scope(options).lte(field => time)
41
45
  end
42
46
 
43
47
  def after_query(time, options={})
44
- field = by_star_start_field
45
- gte(field => time)
48
+ field = by_star_start_field(options)
49
+ by_star_scope(options).gte(field => time)
46
50
  end
47
51
  end
48
52
 
49
53
  def previous(options={})
50
54
  field = self.class.by_star_start_field
51
- self.class.lt(field => self.send(field)).desc(field).first
55
+ self.class.by_star_scope(options).lt(field => self.send(field)).desc(field).first
52
56
  end
53
57
 
54
58
  def next(options={})
55
59
  field = self.class.by_star_start_field
56
- self.class.gt(field => self.send(field)).asc(field).first
60
+ self.class.by_star_scope(options).gt(field => self.send(field)).asc(field).first
57
61
  end
58
62
  end
59
63
  end
@@ -1,3 +1,3 @@
1
1
  module ByStar
2
- VERSION = '2.2.0.rc1'
2
+ VERSION = '2.2.0'
3
3
  end
@@ -1,6 +1,10 @@
1
1
  class Post < ActiveRecord::Base
2
2
  end
3
3
 
4
+ class Appointment < ActiveRecord::Base
5
+ by_star_field scope: ->{ where(day_of_month: 1) }
6
+ end
7
+
4
8
  class Event < ActiveRecord::Base
5
9
  by_star_field :start_time, :end_time, offset: 3.hours
6
10
  end
@@ -3,9 +3,17 @@ ActiveRecord::Schema.define do
3
3
 
4
4
  create_table :posts, :force => true do |t|
5
5
  t.timestamps
6
+ t.integer :day_of_month
6
7
  end
7
8
 
8
9
  create_table :events, :force => true do |t|
10
+ t.timestamps
9
11
  t.datetime :start_time, :end_time
12
+ t.integer :day_of_month
13
+ end
14
+
15
+ create_table :appointments, :force => true do |t|
16
+ t.timestamps
17
+ t.integer :day_of_month
10
18
  end
11
19
  end
@@ -2,14 +2,28 @@ class Post
2
2
  include Mongoid::Document
3
3
  include Mongoid::Timestamps
4
4
  include Mongoid::ByStar
5
+
6
+ field :day_of_month, type: Integer
7
+ end
8
+
9
+ class Appointment
10
+ include Mongoid::Document
11
+ include Mongoid::Timestamps
12
+ include Mongoid::ByStar
13
+
14
+ field :day_of_month, type: Integer
15
+
16
+ by_star_field scope: ->{ where(day_of_month: 1) }
5
17
  end
6
18
 
7
19
  class Event
8
20
  include Mongoid::Document
21
+ include Mongoid::Timestamps
9
22
  include Mongoid::ByStar
10
23
 
11
24
  field :st, as: :start_time, type: Time
12
25
  field :end_time, type: Time
26
+ field :day_of_month, type: Integer
13
27
 
14
28
  by_star_field :start_time, :end_time, offset: 3.hours
15
29
  end
@@ -1,4 +1,13 @@
1
- %w(2013-12-31
1
+ %w(2013-11-01
2
+ 2013-11-30
3
+ 2013-12-01
4
+ 2013-12-05
5
+ 2013-12-08
6
+ 2013-12-16
7
+ 2013-12-22
8
+ 2013-12-25
9
+ 2013-12-28
10
+ 2013-12-31
2
11
  2014-01-01
3
12
  2014-01-01
4
13
  2014-01-05
@@ -11,6 +20,7 @@
11
20
  2014-03-15
12
21
  2014-04-01
13
22
  2014-04-15).map{|d| Time.zone.parse(d) + 17.hours }.each do |d|
14
- Post.create!(:created_at => d)
15
- Event.create!(:start_time => d - 5.days, :end_time => d + 5.days)
23
+ Post.create!(:created_at => d, day_of_month: d.day)
24
+ Appointment.create!(:created_at => d, day_of_month: d.day)
25
+ Event.create!(:created_at => d, :start_time => d - 5.days, :end_time => d + 5.days, day_of_month: d.day)
16
26
  end
@@ -4,6 +4,7 @@ Dir[File.dirname(__FILE__) + '/../shared/*.rb'].each {|file| require file }
4
4
  describe ActiveRecord do
5
5
  before(:all) do
6
6
  ActiveRecord::Base.default_timezone = :utc
7
+ # ActiveRecord::Base.logger = Logger.new(STDOUT)
7
8
 
8
9
  db_config = YAML::load_file(File.dirname(__FILE__) + '/../../database.yml')
9
10
  if db_config.has_key?('sqlite') && db_config['sqlite'].has_key?('database')
@@ -28,7 +29,9 @@ describe ActiveRecord do
28
29
  it_behaves_like 'by week'
29
30
  it_behaves_like 'by weekend'
30
31
  it_behaves_like 'by year'
32
+ it_behaves_like 'relative'
31
33
  it_behaves_like 'offset parameter'
34
+ it_behaves_like 'scope parameter'
32
35
 
33
36
  it 'should be able to order the result set' do
34
37
  scope = Post.by_year(Time.zone.now.year, :order => 'created_at DESC')
@@ -5,6 +5,7 @@ describe 'Mongoid' do
5
5
 
6
6
  before(:all) do
7
7
  DATABASE_NAME = "mongoid_#{Process.pid}"
8
+ # Moped.logger = Logger.new(STDOUT)
8
9
 
9
10
  Mongoid.configure do |config|
10
11
  config.connect_to DATABASE_NAME
@@ -27,7 +28,9 @@ describe 'Mongoid' do
27
28
  it_behaves_like 'by week'
28
29
  it_behaves_like 'by weekend'
29
30
  it_behaves_like 'by year'
31
+ it_behaves_like 'relative'
30
32
  it_behaves_like 'offset parameter'
33
+ it_behaves_like 'scope parameter'
31
34
 
32
35
  describe '#between_times' do
33
36
  subject { Post.between_times(Time.parse('2014-01-01'), Time.parse('2014-01-06')) }
@@ -11,7 +11,7 @@ shared_examples_for 'by calendar month' do
11
11
 
12
12
  context 'timespan' do
13
13
  subject { Event.by_calendar_month(1) }
14
- its(:count){ should eq 8 }
14
+ its(:count){ should eq 10 }
15
15
  end
16
16
 
17
17
  context 'timespan strict' do
@@ -23,17 +23,17 @@ shared_examples_for 'by calendar month' do
23
23
 
24
24
  context 'point-in-time' do
25
25
  subject { Post.by_calendar_month(12, year: 2013) }
26
- its(:count){ should eq 4 }
26
+ its(:count){ should eq 12 }
27
27
  end
28
28
 
29
29
  context 'timespan' do
30
30
  subject { Event.by_calendar_month('December', year: 2013) }
31
- its(:count){ should eq 5 }
31
+ its(:count){ should eq 13 }
32
32
  end
33
33
 
34
34
  context 'timespan strict' do
35
35
  subject { Event.by_calendar_month('Dec', year: 2013, strict: true) }
36
- its(:count){ should eq 1 }
36
+ its(:count){ should eq 9 }
37
37
  end
38
38
  end
39
39
 
@@ -44,7 +44,7 @@ shared_examples_for 'by calendar month' do
44
44
  end
45
45
 
46
46
  it 'should be able to use an alternative field' do
47
- Event.by_calendar_month(:field => 'end_time').count.should eq 8
47
+ Event.by_calendar_month(:field => 'end_time').count.should eq 9
48
48
  end
49
49
 
50
50
  context ':start_day option' do
@@ -11,7 +11,7 @@ shared_examples_for 'by day' do
11
11
 
12
12
  context 'timespan' do
13
13
  subject { Event.by_day(Time.parse '2014-01-01') }
14
- its(:count){ should eq 4 }
14
+ its(:count){ should eq 5 }
15
15
  end
16
16
 
17
17
  context 'timespan strict' do
@@ -20,7 +20,7 @@ shared_examples_for 'by day' do
20
20
  end
21
21
 
22
22
  it 'should be able to use an alternative field' do
23
- Event.by_day(:field => 'end_time').count.should eq 4
23
+ Event.by_day(:field => 'end_time').count.should eq 0
24
24
  end
25
25
 
26
26
  it 'should support :offset option' do
@@ -37,13 +37,21 @@ shared_examples_for 'by day' do
37
37
 
38
38
  context 'timespan' do
39
39
  subject { Event.today }
40
- its(:count){ should eq 4 }
40
+ its(:count){ should eq 5 }
41
41
  end
42
42
 
43
43
  context 'timespan strict' do
44
44
  subject { Event.today(strict: true) }
45
45
  its(:count){ should eq 0 }
46
46
  end
47
+
48
+ it 'should be able to use an alternative field' do
49
+ Event.today(:field => 'created_at').count.should eq 2
50
+ end
51
+
52
+ it 'should support :offset option' do
53
+ Post.today(:offset => -24.hours).count.should eq 1
54
+ end
47
55
  end
48
56
 
49
57
  describe '#yesterday' do # 2013-12-31
@@ -55,13 +63,21 @@ shared_examples_for 'by day' do
55
63
 
56
64
  context 'timespan' do
57
65
  subject { Event.yesterday }
58
- its(:count){ should eq 4 }
66
+ its(:count){ should eq 5 }
59
67
  end
60
68
 
61
69
  context 'timespan strict' do
62
70
  subject { Event.yesterday(strict: true) }
63
71
  its(:count){ should eq 0 }
64
72
  end
73
+
74
+ it 'should be able to use an alternative field' do
75
+ Event.yesterday(:field => 'created_at').count.should eq 1
76
+ end
77
+
78
+ it 'should support :offset option' do
79
+ Post.yesterday(:offset => 24.hours).count.should eq 2
80
+ end
65
81
  end
66
82
 
67
83
  describe '#tomorrow' do # 2014-01-02
@@ -73,12 +89,20 @@ shared_examples_for 'by day' do
73
89
 
74
90
  context 'timespan' do
75
91
  subject { Event.tomorrow }
76
- its(:count){ should eq 4 }
92
+ its(:count){ should eq 5 }
77
93
  end
78
94
 
79
95
  context 'timespan strict' do
80
96
  subject { Event.tomorrow(strict: true) }
81
97
  its(:count){ should eq 0 }
82
98
  end
99
+
100
+ it 'should be able to use an alternative field' do
101
+ Event.tomorrow(:field => 'created_at').count.should eq 0
102
+ end
103
+
104
+ it 'should support :offset option' do
105
+ Post.tomorrow(:offset => -24.hours).count.should eq 2
106
+ end
83
107
  end
84
108
  end