timely 0.4.2 → 0.5.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 +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/timely/rails/date_group.rb +26 -0
- data/lib/timely/version.rb +1 -1
- data/lib/timely/week_days.rb +10 -0
- data/spec/date_group_spec.rb +58 -1
- data/spec/support/coverage_loader.rb +1 -1
- data/spec/week_days_spec.rb +24 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e311a6b7b3b8f1c2c118f67e3cddc6ef7592091514c64f99c7a8d1f46f617d7a
|
4
|
+
data.tar.gz: ae6d6fa3c929fe97a63ed3e907544e97cafb38d2dc768f95d5cea00057d07864
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f0f48ab52cb955cd0dcc13b89138cc72dc5b444f87589173d346595d822bb12c205a5c93a27c34e5a5ea765807d521931823bd331c4baefa30a48a34e516829
|
7
|
+
data.tar.gz: 7013bcafe2fbed12b92caf1fc9da3b07292050fd643cd05a975495674cf5fbd206c815a4d9e65dafbbc25d2af8fb0c646f40a4cf839e4e8a03c08b1b795ec5d6
|
data/CHANGELOG.md
CHANGED
@@ -7,6 +7,32 @@ module Timely
|
|
7
7
|
validates_presence_of :start_date, :end_date
|
8
8
|
validate :validate_date_range!
|
9
9
|
|
10
|
+
scope :covering_date, lambda { |date|
|
11
|
+
# Suitable for use with joins/merge!
|
12
|
+
where(arel_table[:start_date].lteq(date)).where(arel_table[:end_date].gteq(date))
|
13
|
+
}
|
14
|
+
|
15
|
+
scope :within_range, lambda { |date_range|
|
16
|
+
# IMPORTANT: Required for correctness in case of string param.
|
17
|
+
dates = Array(date_range)
|
18
|
+
scope = covering_date(dates.first)
|
19
|
+
if dates.first != dates.last
|
20
|
+
scope = scope.or(covering_date(dates.last))
|
21
|
+
end
|
22
|
+
scope
|
23
|
+
}
|
24
|
+
|
25
|
+
scope :for_any_weekdays, lambda { |weekdays_int|
|
26
|
+
weekdays_int = weekdays_int.to_i
|
27
|
+
where((arel_table[:weekdays_bit_array] & weekdays_int).not_eq(0))
|
28
|
+
.or(where(weekdays_bit_array: nil))
|
29
|
+
}
|
30
|
+
|
31
|
+
scope :applying_for_duration, lambda { |date_range|
|
32
|
+
weekdays_int = Timely::WeekDays.from_range(date_range).weekdays_int
|
33
|
+
within_range(date_range).for_any_weekdays(weekdays_int)
|
34
|
+
}
|
35
|
+
|
10
36
|
def includes_date?(date)
|
11
37
|
date >= start_date && date <= end_date && weekdays.applies_for_date?(date)
|
12
38
|
end
|
data/lib/timely/version.rb
CHANGED
data/lib/timely/week_days.rb
CHANGED
@@ -2,6 +2,16 @@ module Timely
|
|
2
2
|
class WeekDays
|
3
3
|
WEEKDAY_KEYS = %i[sun mon tue wed thu fri sat]
|
4
4
|
|
5
|
+
def self.from_range(date_range)
|
6
|
+
dates = Array(date_range)
|
7
|
+
return ALL_WEEKDAYS if dates.count >= WEEKDAY_KEYS.count
|
8
|
+
|
9
|
+
new(dates.each_with_object({}) { |date, result|
|
10
|
+
# e.g. {3: true, 5: true}
|
11
|
+
result[date.to_date.wday] = true
|
12
|
+
})
|
13
|
+
end
|
14
|
+
|
5
15
|
# Create a new Weekdays object
|
6
16
|
# weekdays can be in three formats
|
7
17
|
# integer representing binary string
|
data/spec/date_group_spec.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require "spec_helper"
|
2
|
-
|
2
|
+
|
3
|
+
|
4
|
+
RSpec.describe Timely::DateGroup do
|
3
5
|
before do
|
4
6
|
@date_group = Timely::DateGroup.new(
|
5
7
|
:start_date => '2000-01-01', :end_date => '2000-01-03', :weekdays => %w(1 1 1 1 1 1 1)
|
@@ -24,3 +26,58 @@ describe Timely::DateGroup do
|
|
24
26
|
expect(@date_group.applicable_for_duration?(Timely::DateRange.new('2012-01-01'.to_date, '2012-01-03'.to_date))).to be true
|
25
27
|
end
|
26
28
|
end
|
29
|
+
|
30
|
+
|
31
|
+
RSpec.describe 'Timely::DateGroup.for_any_weekdays' do
|
32
|
+
let(:date_range) { ('2019-10-17'.to_date)..('2019-10-18'.to_date) }
|
33
|
+
let(:weekdays_int) { Timely::WeekDays.from_range(date_range).weekdays_int }
|
34
|
+
|
35
|
+
let(:special_group) {
|
36
|
+
Timely::DateGroup.create(start_date: date_range.first, end_date: date_range.last).tap { |date_group|
|
37
|
+
date_group.update_column(:weekdays_bit_array, nil)
|
38
|
+
}.reload
|
39
|
+
}
|
40
|
+
|
41
|
+
let!(:date_groups) { [
|
42
|
+
Timely::DateGroup.create(start_date: date_range.first, end_date: date_range.last, weekdays: { thu: true }),
|
43
|
+
Timely::DateGroup.create(start_date: date_range.first, end_date: date_range.last, weekdays: { mon: true }),
|
44
|
+
special_group,
|
45
|
+
] }
|
46
|
+
|
47
|
+
RSpec.shared_examples 'finds expected date groups' do
|
48
|
+
it 'finds expected date groups' do
|
49
|
+
includes_date_groups.each do |date_group|
|
50
|
+
expect(date_group.includes_date?(date_range.first)).to eq(true)
|
51
|
+
end
|
52
|
+
expected_groups.each do |date_group|
|
53
|
+
expect(scoped_result).to include(date_group)
|
54
|
+
end
|
55
|
+
absent_groups.each do |date_group|
|
56
|
+
expect(date_group.includes_date?(date_range.first)).to eq(false)
|
57
|
+
expect(scoped_result).not_to include(date_group)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context '#within_range' do
|
63
|
+
let(:scoped_result) { Timely::DateGroup.within_range(date_range).to_a }
|
64
|
+
let(:expected_groups) { [ date_groups[0], date_groups[1], date_groups[2] ] }
|
65
|
+
let(:absent_groups) { [ ] }
|
66
|
+
let(:includes_date_groups) { [] }
|
67
|
+
it_behaves_like 'finds expected date groups'
|
68
|
+
end
|
69
|
+
|
70
|
+
let(:includes_date_groups) { expected_groups }
|
71
|
+
let(:expected_groups) { [ date_groups[0], date_groups[2] ] }
|
72
|
+
let(:absent_groups) { [ date_groups[1] ] }
|
73
|
+
|
74
|
+
context '#for_any_weekdays' do
|
75
|
+
let(:scoped_result) { Timely::DateGroup.for_any_weekdays(weekdays_int).to_a }
|
76
|
+
it_behaves_like 'finds expected date groups'
|
77
|
+
end
|
78
|
+
|
79
|
+
context '#applying_for_duration' do
|
80
|
+
let(:scoped_result) { Timely::DateGroup.applying_for_duration(date_range).to_a }
|
81
|
+
it_behaves_like 'finds expected date groups'
|
82
|
+
end
|
83
|
+
end
|
data/spec/week_days_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Timely::WeekDays do
|
3
|
+
RSpec.describe Timely::WeekDays do
|
4
4
|
before do
|
5
5
|
@weekdays = Timely::WeekDays.new(:tue => true, :thu => true)
|
6
6
|
end
|
@@ -49,3 +49,26 @@ describe Timely::WeekDays do
|
|
49
49
|
expect(Timely::WeekDays.new(%w(1 1 1 1 1 0 1)).all_days?).to be false
|
50
50
|
end
|
51
51
|
end
|
52
|
+
|
53
|
+
RSpec.describe 'Timely::WeekDays.from_range' do
|
54
|
+
{
|
55
|
+
'single date as string': { date_range: '2019-10-17', expected_weekdays: [ :thu ] },
|
56
|
+
'single date as object': { date_range: '2019-10-17'.to_date, expected_weekdays: [ :thu ] },
|
57
|
+
'range with strings': {
|
58
|
+
date_range: '2019-10-17'..'2019-10-18',
|
59
|
+
expected_weekdays: [ :thu, :fri ],
|
60
|
+
},
|
61
|
+
'range with objects': {
|
62
|
+
date_range: ('2019-10-17'.to_date)..('2019-10-18'.to_date),
|
63
|
+
expected_weekdays: [ :thu, :fri ],
|
64
|
+
},
|
65
|
+
}.each do |type, data|
|
66
|
+
it "#{type} has correct weekdays and applies for dates" do
|
67
|
+
weekdays = Timely::WeekDays.from_range(data[:date_range])
|
68
|
+
expect(weekdays.weekdays).to eq(data[:expected_weekdays])
|
69
|
+
Array(data[:date_range]).each do |date|
|
70
|
+
expect(weekdays.applies_for_date?(date.to_date)).to eq(true)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: timely
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Noack
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-10-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|