rrule 0.4.1 → 0.4.2
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 +5 -5
- data/.gitignore +2 -0
- data/.rubocop.yml +25 -0
- data/.travis.yml +6 -1
- data/Gemfile +9 -0
- data/Rakefile +9 -3
- data/lib/rrule.rb +4 -0
- data/lib/rrule/context.rb +5 -3
- data/lib/rrule/filters/by_month.rb +2 -0
- data/lib/rrule/filters/by_month_day.rb +2 -0
- data/lib/rrule/filters/by_week_day.rb +2 -0
- data/lib/rrule/filters/by_week_number.rb +2 -0
- data/lib/rrule/filters/by_year_day.rb +3 -1
- data/lib/rrule/frequencies/daily.rb +2 -0
- data/lib/rrule/frequencies/frequency.rb +4 -12
- data/lib/rrule/frequencies/monthly.rb +2 -0
- data/lib/rrule/frequencies/simple_weekly.rb +6 -6
- data/lib/rrule/frequencies/weekly.rb +2 -0
- data/lib/rrule/frequencies/yearly.rb +2 -0
- data/lib/rrule/generators/all_occurrences.rb +2 -0
- data/lib/rrule/generators/by_set_position.rb +2 -0
- data/lib/rrule/generators/generator.rb +3 -1
- data/lib/rrule/rule.rb +18 -33
- data/lib/rrule/version.rb +5 -0
- data/lib/rrule/weekday.rb +3 -1
- data/rrule.gemspec +16 -10
- data/scripts/benchmark.rb +3 -1
- metadata +13 -56
- data/spec/context_spec.rb +0 -261
- data/spec/filters/by_month_day_spec.rb +0 -35
- data/spec/filters/by_month_spec.rb +0 -35
- data/spec/filters/by_week_day_spec.rb +0 -35
- data/spec/filters/by_week_number_spec.rb +0 -41
- data/spec/filters/by_year_day_spec.rb +0 -35
- data/spec/frequencies/daily_spec.rb +0 -62
- data/spec/frequencies/monthly_spec.rb +0 -63
- data/spec/frequencies/simple_weekly_spec.rb +0 -32
- data/spec/frequencies/weekly_spec.rb +0 -92
- data/spec/frequencies/yearly_spec.rb +0 -54
- data/spec/generators/all_occurrences_spec.rb +0 -44
- data/spec/generators/by_set_position_spec.rb +0 -39
- data/spec/generators/generator_spec.rb +0 -110
- data/spec/rule_spec.rb +0 -2338
- data/spec/spec_helper.rb +0 -23
- data/spec/weekday_spec.rb +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 110d8805d4e642767c86d7e23f0b77d8d42a0a11ef3c5edf5c08ee2d8f78d4ab
|
4
|
+
data.tar.gz: 8dcd49b64e8300b5facdfb92c72485b6c87b3003ba9dc87116fe13ca9bd44bf5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 467ad003c49dea6fb320775f59a33f739405edd0b330b87512ed4e183bcd757f8e16e4deda296c6f916055056ba98ae0be623df3f78fc9b8c39b790ca4198db6
|
7
|
+
data.tar.gz: c51e63c57919c57c4954b66c4b55d77ed6f513117a338ea76c595239433a1bc983c50706e642ba3b7b596aaf1feb3d111743ba8bd945c61d372f099656170dbb
|
data/.gitignore
CHANGED
data/.rubocop.yml
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.3
|
3
|
+
|
4
|
+
Layout:
|
5
|
+
Enabled: false
|
6
|
+
|
7
|
+
Lint/NonLocalExitFromIterator:
|
8
|
+
Enabled: false
|
9
|
+
|
10
|
+
Metrics:
|
11
|
+
Enabled: false
|
12
|
+
|
13
|
+
Naming:
|
14
|
+
Enabled: false
|
15
|
+
|
16
|
+
Style/Documentation:
|
17
|
+
Enabled: false
|
18
|
+
Style/MultilineBlockChain:
|
19
|
+
Enabled: false
|
20
|
+
Style/NumericPredicate:
|
21
|
+
Enabled: false
|
22
|
+
Style/RescueModifier:
|
23
|
+
Enabled: false
|
24
|
+
Style/TrailingCommaInArrayLiteral:
|
25
|
+
EnforcedStyleForMultiline: comma
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -1,12 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rubygems'
|
2
4
|
require 'rake'
|
5
|
+
require 'bundler/gem_tasks'
|
3
6
|
require 'rspec/core/rake_task'
|
4
|
-
require File.expand_path('
|
7
|
+
require File.expand_path('lib/rrule', __dir__)
|
5
8
|
|
6
9
|
RSpec::Core::RakeTask.new(:spec)
|
7
10
|
|
11
|
+
require 'rubocop/rake_task'
|
12
|
+
RuboCop::RakeTask.new
|
13
|
+
|
8
14
|
namespace :spec do
|
9
|
-
task :
|
15
|
+
task all: ['spec']
|
10
16
|
end
|
11
17
|
|
12
|
-
task :
|
18
|
+
task default: %w[spec:all rubocop]
|
data/lib/rrule.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'active_support/all'
|
2
4
|
|
3
5
|
module RRule
|
@@ -22,6 +24,8 @@ module RRule
|
|
22
24
|
autoload :AllOccurrences, 'rrule/generators/all_occurrences'
|
23
25
|
autoload :BySetPosition, 'rrule/generators/by_set_position'
|
24
26
|
|
27
|
+
WEEKDAYS = %w[SU MO TU WE TH FR SA].freeze
|
28
|
+
|
25
29
|
def self.parse(rrule, **options)
|
26
30
|
Rule.new(rrule, **options)
|
27
31
|
end
|
data/lib/rrule/context.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RRule
|
2
4
|
class Context
|
3
5
|
attr_reader :options, :dtstart, :tz, :day_of_year_mask, :year
|
@@ -17,14 +19,14 @@ module RRule
|
|
17
19
|
possible_date_ranges = []
|
18
20
|
if options[:freq] == 'YEARLY'
|
19
21
|
if options[:bymonth]
|
20
|
-
options[:bymonth].each do |
|
21
|
-
possible_date_ranges.push(elapsed_days_in_year_by_month[(
|
22
|
+
options[:bymonth].each do |mon|
|
23
|
+
possible_date_ranges.push(elapsed_days_in_year_by_month[(mon - 1)..mon])
|
22
24
|
end
|
23
25
|
else
|
24
26
|
possible_date_ranges = [[0, year_length_in_days]]
|
25
27
|
end
|
26
28
|
elsif options[:freq] == 'MONTHLY'
|
27
|
-
possible_date_ranges = [elapsed_days_in_year_by_month[(month - 1)..
|
29
|
+
possible_date_ranges = [elapsed_days_in_year_by_month[(month - 1)..month]]
|
28
30
|
end
|
29
31
|
|
30
32
|
unless possible_date_ranges.empty?
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RRule
|
2
4
|
class ByYearDay
|
3
5
|
def initialize(by_year_days, context)
|
@@ -6,7 +8,7 @@ module RRule
|
|
6
8
|
end
|
7
9
|
|
8
10
|
def reject?(i)
|
9
|
-
!by_year_days.empty? &&
|
11
|
+
!by_year_days.empty? &&
|
10
12
|
((i < context.year_length_in_days && !by_year_days.include?(i + 1) && !by_year_days.include?(i - context.year_length_in_days)) ||
|
11
13
|
(i >= context.year_length_in_days && !by_year_days.include?(i + 1 - context.year_length_in_days) && !by_year_days.include?(i - context.year_length_in_days - context.next_year_length_in_days)))
|
12
14
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RRule
|
2
4
|
class Frequency
|
3
5
|
attr_reader :current_date, :filters, :generator, :timeset
|
@@ -12,9 +14,7 @@ module RRule
|
|
12
14
|
|
13
15
|
def advance
|
14
16
|
@current_date = current_date.advance(advance_by).tap do |new_date|
|
15
|
-
unless same_month(current_date, new_date)
|
16
|
-
context.rebuild(new_date.year, new_date.month)
|
17
|
-
end
|
17
|
+
context.rebuild(new_date.year, new_date.month) unless same_month(current_date, new_date)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
@@ -32,10 +32,6 @@ module RRule
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
def possible_days
|
36
|
-
fail NotImplementedError
|
37
|
-
end
|
38
|
-
|
39
35
|
def self.for_options(options)
|
40
36
|
case options[:freq]
|
41
37
|
when 'DAILY'
|
@@ -51,7 +47,7 @@ module RRule
|
|
51
47
|
when 'YEARLY'
|
52
48
|
Yearly
|
53
49
|
else
|
54
|
-
raise InvalidRRule,
|
50
|
+
raise InvalidRRule, 'Valid FREQ value is required'
|
55
51
|
end
|
56
52
|
end
|
57
53
|
|
@@ -62,9 +58,5 @@ module RRule
|
|
62
58
|
def same_month(first_date, second_date)
|
63
59
|
first_date.month == second_date.month && first_date.year == second_date.year
|
64
60
|
end
|
65
|
-
|
66
|
-
def advance_by
|
67
|
-
fail NotImplementedError
|
68
|
-
end
|
69
61
|
end
|
70
62
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RRule
|
2
4
|
class SimpleWeekly < Frequency
|
3
5
|
def next_occurrences
|
@@ -8,15 +10,13 @@ module RRule
|
|
8
10
|
end
|
9
11
|
|
10
12
|
def correct_current_date_if_needed
|
11
|
-
if context.options[:byweekday].present?
|
12
|
-
|
13
|
+
target_wday = if context.options[:byweekday].present?
|
14
|
+
context.options[:byweekday].first.index
|
13
15
|
else
|
14
|
-
|
16
|
+
context.dtstart.wday
|
15
17
|
end
|
16
18
|
|
17
|
-
while @current_date.wday != target_wday
|
18
|
-
@current_date = @current_date + 1.day
|
19
|
-
end
|
19
|
+
@current_date += 1.day while @current_date.wday != target_wday
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
data/lib/rrule/rule.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RRule
|
2
4
|
class Rule
|
3
5
|
include Enumerable
|
@@ -25,11 +27,8 @@ module RRule
|
|
25
27
|
end
|
26
28
|
|
27
29
|
def each(floor_date: nil)
|
28
|
-
floor_date ||= dtstart
|
29
30
|
# If we have a COUNT or INTERVAL option, we have to start at dtstart, because those are relative to dtstart
|
30
|
-
if count_or_interval_present?
|
31
|
-
floor_date = dtstart
|
32
|
-
end
|
31
|
+
floor_date = dtstart if count_or_interval_present? || floor_date.nil? || dtstart > floor_date
|
33
32
|
|
34
33
|
return enum_for(:each, floor_date: floor_date) unless block_given?
|
35
34
|
context = Context.new(options, dtstart, tz)
|
@@ -39,30 +38,20 @@ module RRule
|
|
39
38
|
count = options[:count]
|
40
39
|
|
41
40
|
filters = []
|
42
|
-
if options[:bymonth]
|
43
|
-
filters.push(ByMonth.new(options[:bymonth], context))
|
44
|
-
end
|
41
|
+
filters.push(ByMonth.new(options[:bymonth], context)) if options[:bymonth]
|
45
42
|
|
46
|
-
if options[:byweekno]
|
47
|
-
filters.push(ByWeekNumber.new(options[:byweekno], context))
|
48
|
-
end
|
43
|
+
filters.push(ByWeekNumber.new(options[:byweekno], context)) if options[:byweekno]
|
49
44
|
|
50
|
-
if options[:byweekday]
|
51
|
-
filters.push(ByWeekDay.new(options[:byweekday], context))
|
52
|
-
end
|
45
|
+
filters.push(ByWeekDay.new(options[:byweekday], context)) if options[:byweekday]
|
53
46
|
|
54
|
-
if options[:byyearday]
|
55
|
-
filters.push(ByYearDay.new(options[:byyearday], context))
|
56
|
-
end
|
47
|
+
filters.push(ByYearDay.new(options[:byyearday], context)) if options[:byyearday]
|
57
48
|
|
58
|
-
if options[:bymonthday]
|
59
|
-
filters.push(ByMonthDay.new(options[:bymonthday], context))
|
60
|
-
end
|
49
|
+
filters.push(ByMonthDay.new(options[:bymonthday], context)) if options[:bymonthday]
|
61
50
|
|
62
|
-
if options[:bysetpos]
|
63
|
-
|
51
|
+
generator = if options[:bysetpos]
|
52
|
+
BySetPosition.new(options[:bysetpos], context)
|
64
53
|
else
|
65
|
-
|
54
|
+
AllOccurrences.new(context)
|
66
55
|
end
|
67
56
|
|
68
57
|
frequency = Frequency.for_options(options).new(context, filters, generator, timeset, start_date: floor_date)
|
@@ -117,15 +106,15 @@ module RRule
|
|
117
106
|
i = begin
|
118
107
|
Integer(value)
|
119
108
|
rescue ArgumentError
|
120
|
-
raise InvalidRRule,
|
109
|
+
raise InvalidRRule, 'COUNT must be a non-negative integer'
|
121
110
|
end
|
122
|
-
raise InvalidRRule,
|
111
|
+
raise InvalidRRule, 'COUNT must be a non-negative integer' if i < 0
|
123
112
|
options[:count] = i
|
124
113
|
when 'UNTIL'
|
125
114
|
options[:until] = Time.parse(value)
|
126
115
|
when 'INTERVAL'
|
127
116
|
i = Integer(value) rescue 0
|
128
|
-
raise InvalidRRule,
|
117
|
+
raise InvalidRRule, 'INTERVAL must be a positive integer' unless i > 0
|
129
118
|
options[:interval] = i
|
130
119
|
when 'BYHOUR'
|
131
120
|
options[:byhour] = value.split(',').compact.map(&:to_i)
|
@@ -138,7 +127,7 @@ module RRule
|
|
138
127
|
when 'BYSETPOS'
|
139
128
|
options[:bysetpos] = value.split(',').map(&:to_i)
|
140
129
|
when 'WKST'
|
141
|
-
options[:wkst] =
|
130
|
+
options[:wkst] = RRule::WEEKDAYS.index(value)
|
142
131
|
when 'BYMONTH'
|
143
132
|
options[:bymonth] = value.split(',').compact.map(&:to_i)
|
144
133
|
when 'BYMONTHDAY'
|
@@ -150,12 +139,10 @@ module RRule
|
|
150
139
|
end
|
151
140
|
end
|
152
141
|
|
153
|
-
|
142
|
+
unless options[:byweekno] || options[:byyearday] || options[:bymonthday] || options[:byweekday]
|
154
143
|
case options[:freq]
|
155
144
|
when 'YEARLY'
|
156
|
-
unless options[:bymonth]
|
157
|
-
options[:bymonth] = [dtstart.month]
|
158
|
-
end
|
145
|
+
options[:bymonth] = [dtstart.month] unless options[:bymonth]
|
159
146
|
options[:bymonthday] = [dtstart.day]
|
160
147
|
when 'MONTHLY'
|
161
148
|
options[:bymonthday] = [dtstart.day]
|
@@ -165,9 +152,7 @@ module RRule
|
|
165
152
|
end
|
166
153
|
end
|
167
154
|
|
168
|
-
unless options[:byweekday].nil?
|
169
|
-
options[:byweekday], options[:bynweekday] = options[:byweekday].partition { |wday| wday.ordinal.nil? }
|
170
|
-
end
|
155
|
+
options[:byweekday], options[:bynweekday] = options[:byweekday].partition { |wday| wday.ordinal.nil? } unless options[:byweekday].nil?
|
171
156
|
|
172
157
|
options[:timeset] = [{ hour: (options[:byhour].presence || dtstart.hour), minute: (options[:byminute].presence || dtstart.min), second: (options[:bysecond].presence || dtstart.sec) }]
|
173
158
|
|
data/lib/rrule/weekday.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RRule
|
2
4
|
class Weekday
|
3
5
|
attr_reader :index, :ordinal
|
@@ -9,7 +11,7 @@ module RRule
|
|
9
11
|
|
10
12
|
def self.parse(weekday)
|
11
13
|
match = /([+-]?\d)?([A-Z]{2})/.match(weekday)
|
12
|
-
index =
|
14
|
+
index = RRule::WEEKDAYS.index(match[2])
|
13
15
|
ordinal = match[1] ? match[1].to_i : nil
|
14
16
|
new(index, ordinal)
|
15
17
|
end
|
data/rrule.gemspec
CHANGED
@@ -1,20 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'rrule/version'
|
6
|
+
|
1
7
|
Gem::Specification.new do |s|
|
2
8
|
s.name = 'rrule'
|
3
|
-
s.version =
|
4
|
-
s.date = '2018-04-24'
|
9
|
+
s.version = RRule::VERSION
|
5
10
|
s.summary = 'RRule expansion'
|
6
11
|
s.description = 'A gem for expanding dates according to the RRule specification'
|
7
12
|
s.authors = ['Ryan Mitchell']
|
8
13
|
s.email = 'rmitchell@squareup.com'
|
9
|
-
s.files = `git ls-files`.split(
|
10
|
-
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
14
|
+
s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
11
15
|
s.require_paths = ['lib']
|
12
|
-
s.homepage = '
|
16
|
+
s.homepage = 'https://rubygems.org/gems/rrule'
|
17
|
+
s.metadata = {
|
18
|
+
'homepage' => 'https://rubygems.org/gems/rrule',
|
19
|
+
'source_code_uri' => 'https://github.com/square/ruby-rrule',
|
20
|
+
'bug_tracker_uri' => 'https://github.com/square/ruby-rrule/issues',
|
21
|
+
'changelog_uri' => 'https://github.com/square/ruby-rrule/blob/master/CHANGELOG.md'
|
22
|
+
}
|
13
23
|
|
14
|
-
|
15
|
-
# or Rational. This enables Time to finally work with years after 2038 which
|
16
|
-
# is critical for this library.
|
17
|
-
s.required_ruby_version = '>= 1.9.2'
|
24
|
+
s.required_ruby_version = '>= 2.3.0'
|
18
25
|
s.add_runtime_dependency 'activesupport', '>= 4.1'
|
19
|
-
s.add_development_dependency 'rspec', '~> 3.4'
|
20
26
|
end
|