ta_by_star 4.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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +59 -0
- data/Gemfile +18 -0
- data/MIT-LICENSE +20 -0
- data/README.md +616 -0
- data/Rakefile +18 -0
- data/UPGRADING +4 -0
- data/by_star.gemspec +34 -0
- data/cleaner.rb +25 -0
- data/lib/by_star/base.rb +76 -0
- data/lib/by_star/between.rb +190 -0
- data/lib/by_star/directional.rb +35 -0
- data/lib/by_star/kernel/date.rb +41 -0
- data/lib/by_star/kernel/in_time_zone.rb +20 -0
- data/lib/by_star/kernel/time.rb +41 -0
- data/lib/by_star/normalization.rb +156 -0
- data/lib/by_star/orm/active_record/by_star.rb +75 -0
- data/lib/by_star/orm/mongoid/by_star.rb +90 -0
- data/lib/by_star/orm/mongoid/reorder.rb +23 -0
- data/lib/by_star/version.rb +3 -0
- data/lib/by_star.rb +18 -0
- data/spec/database.yml +15 -0
- data/spec/fixtures/active_record/models.rb +12 -0
- data/spec/fixtures/active_record/schema.rb +19 -0
- data/spec/fixtures/mongoid/models.rb +31 -0
- data/spec/fixtures/shared/seeds.rb +36 -0
- data/spec/gemfiles/Gemfile.rails +5 -0
- data/spec/gemfiles/Gemfile.rails32 +7 -0
- data/spec/gemfiles/Gemfile.rails40 +7 -0
- data/spec/gemfiles/Gemfile.rails41 +7 -0
- data/spec/gemfiles/Gemfile.rails42 +7 -0
- data/spec/gemfiles/Gemfile.rails50 +7 -0
- data/spec/gemfiles/Gemfile.rails51 +7 -0
- data/spec/gemfiles/Gemfile.rails52 +7 -0
- data/spec/gemfiles/Gemfile.rails60 +7 -0
- data/spec/gemfiles/Gemfile.rails61 +7 -0
- data/spec/integration/active_record/active_record_spec.rb +41 -0
- data/spec/integration/mongoid/mongoid_spec.rb +39 -0
- data/spec/integration/shared/at_time.rb +53 -0
- data/spec/integration/shared/between_dates.rb +99 -0
- data/spec/integration/shared/between_times.rb +99 -0
- data/spec/integration/shared/by_calendar_month.rb +55 -0
- data/spec/integration/shared/by_cweek.rb +54 -0
- data/spec/integration/shared/by_day.rb +120 -0
- data/spec/integration/shared/by_direction.rb +126 -0
- data/spec/integration/shared/by_fortnight.rb +48 -0
- data/spec/integration/shared/by_month.rb +50 -0
- data/spec/integration/shared/by_quarter.rb +49 -0
- data/spec/integration/shared/by_week.rb +54 -0
- data/spec/integration/shared/by_weekend.rb +49 -0
- data/spec/integration/shared/by_year.rb +48 -0
- data/spec/integration/shared/index_scope_parameter.rb +111 -0
- data/spec/integration/shared/offset_parameter.rb +32 -0
- data/spec/integration/shared/order_parameter.rb +36 -0
- data/spec/integration/shared/relative.rb +174 -0
- data/spec/spec_helper.rb +33 -0
- data/spec/unit/kernel_date_spec.rb +113 -0
- data/spec/unit/kernel_time_spec.rb +57 -0
- data/spec/unit/normalization_spec.rb +384 -0
- data/tmp/.gitignore +1 -0
- metadata +298 -0
@@ -0,0 +1,90 @@
|
|
1
|
+
# In keeping with Mongoid standards, this module must be included into your model class, i.e.
|
2
|
+
#
|
3
|
+
# include Mongoid::ByStar
|
4
|
+
#
|
5
|
+
module Mongoid
|
6
|
+
module ByStar
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
include ::ByStar::Base
|
11
|
+
|
12
|
+
alias_method :original_by_star_end_field, :by_star_end_field
|
13
|
+
alias_method :original_by_star_start_field, :by_star_start_field
|
14
|
+
|
15
|
+
def by_star_end_field(options = {})
|
16
|
+
database_field_name original_by_star_end_field(options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def by_star_start_field(options = {})
|
20
|
+
database_field_name original_by_star_start_field(options)
|
21
|
+
end
|
22
|
+
|
23
|
+
def by_star_default_field
|
24
|
+
:created_at
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
|
29
|
+
def by_star_point_query(scope, field, start_time, end_time)
|
30
|
+
range = start_time..end_time
|
31
|
+
scope.where(field => range)
|
32
|
+
end
|
33
|
+
|
34
|
+
def by_star_span_strict_query(scope, start_field, end_field, start_time, end_time)
|
35
|
+
range = start_time..end_time
|
36
|
+
scope.where(start_field => range).where(end_field => range)
|
37
|
+
end
|
38
|
+
|
39
|
+
def by_star_span_loose_query(scope, start_field, end_field, start_time, end_time, options)
|
40
|
+
index_scope = by_star_eval_index_scope(start_time, end_time, options)
|
41
|
+
scope = scope.gt(end_field => start_time).lt(start_field => end_time)
|
42
|
+
scope = scope.gte(start_field => index_scope) if index_scope
|
43
|
+
scope
|
44
|
+
end
|
45
|
+
|
46
|
+
def by_star_point_overlap_query(scope, field, time)
|
47
|
+
scope.where(field => time)
|
48
|
+
end
|
49
|
+
|
50
|
+
def by_star_span_overlap_query(scope, start_field, end_field, time, options)
|
51
|
+
index_scope = by_star_eval_index_scope(time, time, options)
|
52
|
+
scope = scope.gt(end_field => time).lte(start_field => time)
|
53
|
+
scope = scope.gte(start_field => index_scope) if index_scope
|
54
|
+
scope
|
55
|
+
end
|
56
|
+
|
57
|
+
def by_star_before_query(scope, field, time)
|
58
|
+
scope.lte(field => time)
|
59
|
+
end
|
60
|
+
|
61
|
+
def by_star_after_query(scope, field, time)
|
62
|
+
scope.gte(field => time)
|
63
|
+
end
|
64
|
+
|
65
|
+
def by_star_order(scope, order)
|
66
|
+
scope.order_by(order)
|
67
|
+
end
|
68
|
+
|
69
|
+
def oldest_query(options={})
|
70
|
+
field = by_star_start_field(options)
|
71
|
+
all.reorder(field => :asc).first
|
72
|
+
end
|
73
|
+
|
74
|
+
def newest_query(options={})
|
75
|
+
field = by_star_start_field(options)
|
76
|
+
all.reorder(field => :desc).first
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def previous(options={})
|
81
|
+
field = self.class.by_star_start_field(options)
|
82
|
+
self.class.lt(field => self.send(field)).reorder(field => :desc).first
|
83
|
+
end
|
84
|
+
|
85
|
+
def next(options={})
|
86
|
+
field = self.class.by_star_start_field(options)
|
87
|
+
self.class.gt(field => self.send(field)).reorder(field => :asc).first
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Backport of `reorder` method from Origin 2.1.0+
|
2
|
+
if defined?(Origin::Optional) && !Origin::Optional.method_defined?(:reorder)
|
3
|
+
module Origin
|
4
|
+
module Optional
|
5
|
+
|
6
|
+
# Instead of merging the order criteria, use this method to completely
|
7
|
+
# replace the existing ordering with the provided.
|
8
|
+
#
|
9
|
+
# @example Replace the ordering.
|
10
|
+
# optional.reorder(name: :asc)
|
11
|
+
#
|
12
|
+
# @param [ Array, Hash, String ] spec The sorting specification.
|
13
|
+
#
|
14
|
+
# @return [ Optional ] The cloned optional.
|
15
|
+
#
|
16
|
+
# @since 2.1.0
|
17
|
+
def reorder(*spec)
|
18
|
+
options.delete(:sort)
|
19
|
+
order_by(*spec)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/by_star.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'by_star/kernel/in_time_zone'
|
2
|
+
require 'by_star/kernel/time'
|
3
|
+
require 'by_star/kernel/date'
|
4
|
+
require 'by_star/normalization'
|
5
|
+
require 'by_star/between'
|
6
|
+
require 'by_star/directional'
|
7
|
+
require 'by_star/base'
|
8
|
+
|
9
|
+
if defined?(ActiveRecord)
|
10
|
+
require 'by_star/orm/active_record/by_star'
|
11
|
+
ActiveRecord::Base.send :include, ByStar::ActiveRecord
|
12
|
+
ActiveRecord::Relation.send :extend, ByStar::ActiveRecord::ClassMethods
|
13
|
+
end
|
14
|
+
|
15
|
+
if defined?(Mongoid)
|
16
|
+
require 'by_star/orm/mongoid/reorder'
|
17
|
+
require 'by_star/orm/mongoid/by_star'
|
18
|
+
end
|
data/spec/database.yml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
sqlite:
|
2
|
+
adapter: sqlite3
|
3
|
+
database: by_star.sqlite3
|
4
|
+
|
5
|
+
postgres:
|
6
|
+
adapter: postgresql
|
7
|
+
database: by_star_test
|
8
|
+
username: <%= ENV.fetch("USER") || "postgres" %>
|
9
|
+
min_messages: warning
|
10
|
+
|
11
|
+
mysql:
|
12
|
+
adapter: mysql2
|
13
|
+
database: by_star_test
|
14
|
+
username: root
|
15
|
+
encoding: utf8
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class Post < ActiveRecord::Base
|
2
|
+
end
|
3
|
+
|
4
|
+
class Appointment < ActiveRecord::Base
|
5
|
+
by_star_field index_scope: ->(start){ start - 5.days }
|
6
|
+
end
|
7
|
+
|
8
|
+
class Event < ActiveRecord::Base
|
9
|
+
by_star_field :start_time, :end_time, offset: 3.hours
|
10
|
+
|
11
|
+
default_scope ->{ order('day_of_month ASC') }
|
12
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
ActiveRecord::Schema.define do
|
2
|
+
self.verbose = false
|
3
|
+
|
4
|
+
create_table :posts, force: true do |t|
|
5
|
+
t.timestamps
|
6
|
+
t.integer :day_of_month
|
7
|
+
end
|
8
|
+
|
9
|
+
create_table :events, force: true do |t|
|
10
|
+
t.timestamps
|
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
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class Post
|
2
|
+
include Mongoid::Document
|
3
|
+
include Mongoid::Timestamps
|
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 index_scope: ->(start){ start - 5.days }
|
17
|
+
end
|
18
|
+
|
19
|
+
class Event
|
20
|
+
include Mongoid::Document
|
21
|
+
include Mongoid::Timestamps
|
22
|
+
include Mongoid::ByStar
|
23
|
+
|
24
|
+
field :st, as: :start_time, type: Time
|
25
|
+
field :end_time, type: Time
|
26
|
+
field :day_of_month, type: Integer
|
27
|
+
|
28
|
+
by_star_field :start_time, :end_time, offset: 3.hours
|
29
|
+
|
30
|
+
default_scope ->{ order_by(day_of_month: :asc) }
|
31
|
+
end
|
@@ -0,0 +1,36 @@
|
|
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
|
11
|
+
2014-01-01
|
12
|
+
2014-01-01
|
13
|
+
2014-01-05
|
14
|
+
2014-01-10
|
15
|
+
2014-01-12
|
16
|
+
2014-01-20
|
17
|
+
2014-02-01
|
18
|
+
2014-02-15
|
19
|
+
2014-03-01
|
20
|
+
2014-03-15
|
21
|
+
2014-04-01
|
22
|
+
2014-04-15).map{|d| Time.zone.parse(d) + 17.hours }.each_with_index do |d, index|
|
23
|
+
Post.create!(created_at: d, updated_at: d + index.days, 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)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Sydney timezone specific records
|
29
|
+
%w(
|
30
|
+
2020-04-05
|
31
|
+
2020-10-04
|
32
|
+
).map{|d| Date.parse(d) }.each do |d|
|
33
|
+
[1, 4, 5, 10].each do |h|
|
34
|
+
Event.create!(start_time: d + h.hour, end_time: d + h.hour + 30.minutes, created_at: Date.parse('2011-01-01').in_time_zone)
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
Dir[File.dirname(__FILE__) + '/../shared/*.rb'].each {|file| require file }
|
3
|
+
|
4
|
+
describe ActiveRecord do
|
5
|
+
before(:all) do
|
6
|
+
ActiveRecord::Base.default_timezone = :utc
|
7
|
+
# ActiveRecord::Base.logger = Logger.new(STDOUT)
|
8
|
+
database_file = File.dirname(__FILE__) + '/../../database.yml'
|
9
|
+
parsed_config = ERB.new(File.read(database_file)).result
|
10
|
+
db_config = YAML.safe_load(parsed_config)
|
11
|
+
if db_config.has_key?('sqlite') && db_config['sqlite'].has_key?('database')
|
12
|
+
db_config['sqlite']['database'] = File.dirname(__FILE__) + '/../../tmp/' + db_config['sqlite']['database']
|
13
|
+
end
|
14
|
+
|
15
|
+
ActiveRecord::Base.configurations = db_config
|
16
|
+
ActiveRecord::Base.establish_connection(ENV['DB'].try(:to_sym) || :sqlite)
|
17
|
+
load File.dirname(__FILE__) + '/../../fixtures/active_record/schema.rb'
|
18
|
+
load File.dirname(__FILE__) + '/../../fixtures/active_record/models.rb'
|
19
|
+
load File.dirname(__FILE__) + '/../../fixtures/shared/seeds.rb'
|
20
|
+
|
21
|
+
ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + '/../../tmp/activerecord.log')
|
22
|
+
end
|
23
|
+
|
24
|
+
it_behaves_like 'between_times'
|
25
|
+
it_behaves_like 'between_dates'
|
26
|
+
it_behaves_like 'at_time'
|
27
|
+
it_behaves_like 'offset parameter'
|
28
|
+
it_behaves_like 'order parameter'
|
29
|
+
it_behaves_like 'index_scope parameter'
|
30
|
+
it_behaves_like 'by day'
|
31
|
+
it_behaves_like 'by direction'
|
32
|
+
it_behaves_like 'by fortnight'
|
33
|
+
it_behaves_like 'by month'
|
34
|
+
it_behaves_like 'by calendar month'
|
35
|
+
it_behaves_like 'by quarter'
|
36
|
+
it_behaves_like 'by week'
|
37
|
+
it_behaves_like 'by cweek'
|
38
|
+
it_behaves_like 'by weekend'
|
39
|
+
it_behaves_like 'by year'
|
40
|
+
it_behaves_like 'relative'
|
41
|
+
end if testing_active_record?
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
Dir[File.dirname(__FILE__) + '/../shared/*.rb'].each {|file| require file }
|
3
|
+
|
4
|
+
describe 'Mongoid' do
|
5
|
+
|
6
|
+
before(:all) do
|
7
|
+
DATABASE_NAME = "mongoid_#{Process.pid}"
|
8
|
+
# Moped.logger = Logger.new(STDOUT)
|
9
|
+
|
10
|
+
Mongoid.configure do |config|
|
11
|
+
config.connect_to DATABASE_NAME
|
12
|
+
end
|
13
|
+
|
14
|
+
load File.dirname(__FILE__) + '/../../fixtures/mongoid/models.rb'
|
15
|
+
load File.dirname(__FILE__) + '/../../fixtures/shared/seeds.rb'
|
16
|
+
end
|
17
|
+
|
18
|
+
after(:all) do
|
19
|
+
Mongoid.purge!
|
20
|
+
end
|
21
|
+
|
22
|
+
it_behaves_like 'between_times'
|
23
|
+
it_behaves_like 'between_dates'
|
24
|
+
it_behaves_like 'at_time'
|
25
|
+
it_behaves_like 'offset parameter'
|
26
|
+
it_behaves_like 'order parameter'
|
27
|
+
it_behaves_like 'index_scope parameter'
|
28
|
+
it_behaves_like 'by day'
|
29
|
+
it_behaves_like 'by direction'
|
30
|
+
it_behaves_like 'by fortnight'
|
31
|
+
it_behaves_like 'by month'
|
32
|
+
it_behaves_like 'by calendar month'
|
33
|
+
it_behaves_like 'by quarter'
|
34
|
+
it_behaves_like 'by week'
|
35
|
+
it_behaves_like 'by cweek'
|
36
|
+
it_behaves_like 'by weekend'
|
37
|
+
it_behaves_like 'by year'
|
38
|
+
it_behaves_like 'relative'
|
39
|
+
end if testing_mongoid?
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
shared_examples_for 'at_time' do
|
4
|
+
|
5
|
+
describe '#at_time' do
|
6
|
+
|
7
|
+
context 'point object' do
|
8
|
+
|
9
|
+
context 'exactly equal' do
|
10
|
+
subject { Post.at_time(Time.zone.parse('2013-12-28 17:00:00')) }
|
11
|
+
it { expect(subject.count).to eql(1) }
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'not exactly equal' do
|
15
|
+
subject { Post.at_time(Time.zone.parse('2013-12-28 17:00:01')) }
|
16
|
+
it { expect(subject.count).to eql(0) }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'timespan object' do
|
21
|
+
|
22
|
+
context 'before start time' do
|
23
|
+
subject { Event.at_time(Time.zone.parse('2013-12-23 16:59:59')) }
|
24
|
+
it { expect(subject.count).to eql(2) }
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'at start time' do
|
28
|
+
subject { Event.at_time(Time.zone.parse('2013-12-23 17:00:00')) }
|
29
|
+
it { expect(subject.count).to eql(3) }
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'after start time' do
|
33
|
+
subject { Event.at_time(Time.zone.parse('2013-12-23 17:00:01')) }
|
34
|
+
it { expect(subject.count).to eql(3) }
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'before end time' do
|
38
|
+
subject { Event.at_time(Time.zone.parse('2013-11-06 16:59:59')) }
|
39
|
+
it { expect(subject.count).to eql(1) }
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'at end time' do
|
43
|
+
subject { Event.at_time(Time.zone.parse('2013-11-06 17:00:00')) }
|
44
|
+
it { expect(subject.count).to eql(0) }
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'after end time' do
|
48
|
+
subject { Event.at_time(Time.zone.parse('2013-11-06 17:00:01')) }
|
49
|
+
it { expect(subject.count).to eql(0) }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
shared_examples_for 'between_dates' do
|
4
|
+
|
5
|
+
describe '#between_dates' do
|
6
|
+
subject { Post.between_dates(Time.zone.parse('2014-01-01'), Time.zone.parse('2014-01-06')) }
|
7
|
+
|
8
|
+
if testing_active_record?
|
9
|
+
it { is_expected.to be_a(ActiveRecord::Relation) }
|
10
|
+
else testing_mongoid?
|
11
|
+
it { is_expected.to be_a(Mongoid::Criteria) }
|
12
|
+
end
|
13
|
+
|
14
|
+
it { expect(subject.count).to eql(3) }
|
15
|
+
|
16
|
+
context 'one-sided query' do
|
17
|
+
|
18
|
+
context 'point query' do
|
19
|
+
|
20
|
+
context 'only start time' do
|
21
|
+
subject { Post.between_dates(Time.zone.parse('2014-01-01'), nil) }
|
22
|
+
it { expect(subject.count).to eql(12) }
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'only end time' do
|
26
|
+
subject { Post.between_dates(nil, Time.zone.parse('2014-01-01')) }
|
27
|
+
it { expect(subject.count).to eql(12) }
|
28
|
+
|
29
|
+
context 'neither start nor end time' do
|
30
|
+
subject { Post.between_dates(nil, nil) }
|
31
|
+
it { expect(subject.count).to eql(22) }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'timespan loose query' do
|
37
|
+
|
38
|
+
context 'only start time' do
|
39
|
+
subject { Event.between_dates(Time.zone.parse('2014-01-01'), nil, strict: false) }
|
40
|
+
it { expect(subject.count).to eql(17) }
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'only end time' do
|
44
|
+
subject { Event.between_dates(nil, Time.zone.parse('2014-01-01'), strict: false) }
|
45
|
+
it { expect(subject.count).to eql(13) }
|
46
|
+
|
47
|
+
context 'neither start nor end time' do
|
48
|
+
subject { Event.between_dates(nil, nil) }
|
49
|
+
it { expect(subject.count).to eql(30) }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'timespan strict query' do
|
55
|
+
|
56
|
+
context 'only start time' do
|
57
|
+
subject { Event.between_dates(Time.zone.parse('2014-01-01'), nil) }
|
58
|
+
it { expect(subject.count).to eql(17) }
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'only end time' do
|
62
|
+
subject { Event.between_dates(nil, Time.zone.parse('2014-01-01')) }
|
63
|
+
it { expect(subject.count).to eql(13) }
|
64
|
+
|
65
|
+
context 'neither start nor end time' do
|
66
|
+
subject { Event.between_dates(nil, nil) }
|
67
|
+
it { expect(subject.count).to eql(30) }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'two-sided query' do
|
74
|
+
context 'DST starts (Sydney)', sydney: true do
|
75
|
+
context 'day before' do
|
76
|
+
subject { Event.between_dates(Date.parse('2020-04-04'), Date.parse('2020-04-04'), offset: 5.hours) }
|
77
|
+
it { expect(subject.count).to eql(3) }
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'same day' do
|
81
|
+
subject { Event.between_dates(Date.parse('2020-04-05'), Date.parse('2020-04-05'), offset: 5.hours) }
|
82
|
+
it { expect(subject.count).to eql(1) }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'when DST ends (Sydney)', sydney: true do
|
87
|
+
context 'day before' do
|
88
|
+
subject { Event.between_dates(Date.parse('2020-10-03'), Date.parse('2020-10-03'), offset: 5.hours) }
|
89
|
+
it { expect(subject.count).to eql(1) }
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'same day' do
|
93
|
+
subject { Event.between_dates(Date.parse('2020-10-04'), Date.parse('2020-10-04'), offset: 5.hours) }
|
94
|
+
it { expect(subject.count).to eql(3) }
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
shared_examples_for 'between_times' do
|
4
|
+
|
5
|
+
describe '#between_times' do
|
6
|
+
subject { Post.between_times(Time.zone.parse('2014-01-01'), Time.zone.parse('2014-01-06')) }
|
7
|
+
|
8
|
+
if testing_active_record?
|
9
|
+
it { is_expected.to be_a(ActiveRecord::Relation) }
|
10
|
+
else testing_mongoid?
|
11
|
+
it { is_expected.to be_a(Mongoid::Criteria) }
|
12
|
+
end
|
13
|
+
|
14
|
+
it { expect(subject.count).to eql(3) }
|
15
|
+
|
16
|
+
context 'one-sided query' do
|
17
|
+
|
18
|
+
context 'point query' do
|
19
|
+
|
20
|
+
context 'only start time' do
|
21
|
+
subject { Post.between_times(Time.zone.parse('2014-01-01'), nil) }
|
22
|
+
it { expect(subject.count).to eql(12) }
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'only end time' do
|
26
|
+
subject { Post.between_times(nil, Time.zone.parse('2014-01-01')) }
|
27
|
+
it { expect(subject.count).to eql(10) }
|
28
|
+
|
29
|
+
context 'neither start nor end time' do
|
30
|
+
subject { Post.between_times(nil, nil) }
|
31
|
+
it { expect(subject.count).to eql(22) }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'timespan loose query' do
|
37
|
+
|
38
|
+
context 'only start time' do
|
39
|
+
subject { Event.between_times(Time.zone.parse('2014-01-01'), nil, strict: false) }
|
40
|
+
it { expect(subject.count).to eql(17) }
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'only end time' do
|
44
|
+
subject { Event.between_times(nil, Time.zone.parse('2014-01-01'), strict: false) }
|
45
|
+
it { expect(subject.count).to eql(13) }
|
46
|
+
|
47
|
+
context 'neither start nor end time' do
|
48
|
+
subject { Event.between_times(nil, nil) }
|
49
|
+
it { expect(subject.count).to eql(30) }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'timespan strict query' do
|
55
|
+
|
56
|
+
context 'only start time' do
|
57
|
+
subject { Event.between_times(Time.zone.parse('2014-01-01'), nil) }
|
58
|
+
it { expect(subject.count).to eql(17) }
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'only end time' do
|
62
|
+
subject { Event.between_times(nil, Time.zone.parse('2014-01-01')) }
|
63
|
+
it { expect(subject.count).to eql(13) }
|
64
|
+
|
65
|
+
context 'neither start nor end time' do
|
66
|
+
subject { Event.between_times(nil, nil) }
|
67
|
+
it { expect(subject.count).to eql(30) }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'two-sided query' do
|
74
|
+
context 'DST starts (Sydney)', sydney: true do
|
75
|
+
context 'day before' do
|
76
|
+
subject { Event.between_times(Date.parse('2020-04-04'), Date.parse('2020-04-04'), offset: 5.hours) }
|
77
|
+
it { expect(subject.count).to eql(3) }
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'same day' do
|
81
|
+
subject { Event.between_times(Date.parse('2020-04-05'), Date.parse('2020-04-05'), offset: 5.hours) }
|
82
|
+
it { expect(subject.count).to eql(1) }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'when DST ends (Sydney)', sydney: true do
|
87
|
+
context 'day before' do
|
88
|
+
subject { Event.between_times(Date.parse('2020-10-03'), Date.parse('2020-10-03'), offset: 5.hours) }
|
89
|
+
it { expect(subject.count).to eql(1) }
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'same day' do
|
93
|
+
subject { Event.between_times(Date.parse('2020-10-04'), Date.parse('2020-10-04'), offset: 5.hours) }
|
94
|
+
it { expect(subject.count).to eql(3) }
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|