diff --git a/.travis.yml b/.travis.yml index 45d99a55..79ccbae8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,32 +10,12 @@ branches: only: - master rvm: - - 1.9.3 - - 2.0 - - 2.1.10 - - 2.2.6 - - 2.3.3 - - 2.4.0 + - 2.3.7 + - 2.4.4 + - 2.5.1 - ruby-head env: - - RAILS_VERSION='~> 3.2' - RAILS_VERSION='~> 4.2' - RAILS_VERSION='~> 5.0' -matrix: - exclude: - - # Rails 5 only runs on ruby 2.3 and up - - rvm: 1.9.3 - env: RAILS_VERSION='~> 5.0' - - rvm: 2.0 - env: RAILS_VERSION='~> 5.0' - - rvm: 2.1.10 - env: RAILS_VERSION='~> 5.0' - - rvm: 2.2.6 - env: RAILS_VERSION='~> 5.0' - - # Rails 3 no longer runs on ruby 2.4 and up - - rvm: 2.4.0 - env: RAILS_VERSION='~> 3.2' - - rvm: ruby-head - env: RAILS_VERSION='~> 3.2' + - RAILS_VERSION='~> 5.1' + - RAILS_VERSION='~> 5.2' diff --git a/CHANGELOG.md b/CHANGELOG.md index 9927a04d..af27f7f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Unreleased + +* [ENHANCEMENT] Drop old versions of Ruby and Ruby on Rails + ## 0.16.3 / 2018-07-23 * [FEATURE] Added support for parsing RDATE from iCal format diff --git a/Gemfile b/Gemfile index 022c86be..7e32e2c5 100644 --- a/Gemfile +++ b/Gemfile @@ -1,11 +1,5 @@ source 'https://rubygems.org' gemspec -compatible_rails_versions = [ - '>= 3.0.0', - ('<5' if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.2.2')) -].compact - -gem 'activesupport', (ENV['RAILS_VERSION'] || compatible_rails_versions), require: false +gem 'activesupport', (ENV['RAILS_VERSION'] || '>= 4.2'), require: false gem 'i18n', require: false -gem 'tzinfo', require: false # only needed explicitly for RAILS_VERSION=3 diff --git a/ice_cube.gemspec b/ice_cube.gemspec index 7dd3fd74..82e431cd 100644 --- a/ice_cube.gemspec +++ b/ice_cube.gemspec @@ -1,4 +1,3 @@ -# encoding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'ice_cube/version' @@ -15,9 +14,7 @@ Gem::Specification.new do |s| s.version = IceCube::VERSION s.platform = Gem::Platform::RUBY s.files = Dir['lib/**/*.rb', 'config/**/*.yml'] - s.test_files = Dir.glob('spec/*.rb') s.require_paths = ['lib'] - s.has_rdoc = true s.add_development_dependency('rake') s.add_development_dependency('rspec', '> 3') diff --git a/lib/ice_cube/builders/hash_builder.rb b/lib/ice_cube/builders/hash_builder.rb index 6c208d41..bc2b6d92 100644 --- a/lib/ice_cube/builders/hash_builder.rb +++ b/lib/ice_cube/builders/hash_builder.rb @@ -1,9 +1,7 @@ module IceCube - class HashBuilder - def initialize(rule = nil) - @hash = { :validations => {}, :rule_type => rule.class.name } + @hash = { validations: {}, rule_type: rule.class.name } end def validations @@ -21,7 +19,5 @@ def validations_array(type) def to_hash @hash end - end - end diff --git a/lib/ice_cube/builders/ical_builder.rb b/lib/ice_cube/builders/ical_builder.rb index 2ba4e646..b45542da 100644 --- a/lib/ice_cube/builders/ical_builder.rb +++ b/lib/ice_cube/builders/ical_builder.rb @@ -1,8 +1,6 @@ module IceCube - class IcalBuilder - - ICAL_DAYS = ['SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA'] + ICAL_DAYS = %w[SU MO TU WE TH FR SA].freeze def initialize @hash = {} @@ -23,9 +21,7 @@ def to_s arr << "FREQ=#{freq.join(',')}" end arr.concat(@hash.map do |key, value| - if value.is_a?(Array) - "#{key}=#{value.join(',')}" - end + "#{key}=#{value.join(',')}" if value.is_a?(Array) end.compact) arr.join(';') end @@ -53,7 +49,5 @@ def self.ical_duration(duration) repr << "#{duration}S" if duration > 0 "PT#{repr}" end - end - end diff --git a/lib/ice_cube/builders/string_builder.rb b/lib/ice_cube/builders/string_builder.rb index dda38dcc..1780d2e4 100644 --- a/lib/ice_cube/builders/string_builder.rb +++ b/lib/ice_cube/builders/string_builder.rb @@ -1,7 +1,5 @@ module IceCube - class StringBuilder - attr_writer :base def initialize @@ -37,14 +35,17 @@ def self.register_formatter(type, &formatter) end module Helpers - # influenced by ActiveSupport's to_sentence def sentence(array) case array.length - when 0 ; '' - when 1 ; array[0].to_s - when 2 ; "#{array[0]}#{IceCube::I18n.t('ice_cube.array.two_words_connector')}#{array[1]}" - else ; "#{array[0...-1].join(IceCube::I18n.t('ice_cube.array.words_connector'))}#{IceCube::I18n.t('ice_cube.array.last_word_connector')}#{array[-1]}" + when 0 + '' + when 1 + array[0].to_s + when 2 + "#{array[0]}#{IceCube::I18n.t('ice_cube.array.two_words_connector')}#{array[1]}" + else + "#{array[0...-1].join(IceCube::I18n.t('ice_cube.array.words_connector'))}#{IceCube::I18n.t('ice_cube.array.last_word_connector')}#{array[-1]}" end end @@ -66,11 +67,7 @@ def ordinal(number) IceCube::I18n.t('ice_cube.integer.ordinals')[:default] number >= 0 ? ord : IceCube::I18n.t("ice_cube.integer.negative", ordinal: ord) end - end - extend Helpers - end - end diff --git a/lib/ice_cube/deprecated.rb b/lib/ice_cube/deprecated.rb index 5e5eed02..d0bdccec 100644 --- a/lib/ice_cube/deprecated.rb +++ b/lib/ice_cube/deprecated.rb @@ -1,6 +1,5 @@ module IceCube module Deprecated - # Define a deprecated alias for a method # @param [Symbol] name - name of method to define # @param [Symbol] replacement - name of method to replace (alias) diff --git a/lib/ice_cube/errors/count_exceeded.rb b/lib/ice_cube/errors/count_exceeded.rb index e864828b..4da92b8f 100644 --- a/lib/ice_cube/errors/count_exceeded.rb +++ b/lib/ice_cube/errors/count_exceeded.rb @@ -1,7 +1,5 @@ module IceCube - # An exception for when a count on a Rule is passed class CountExceeded < StopIteration end - end diff --git a/lib/ice_cube/errors/until_exceeded.rb b/lib/ice_cube/errors/until_exceeded.rb index 84387c2e..010f7735 100644 --- a/lib/ice_cube/errors/until_exceeded.rb +++ b/lib/ice_cube/errors/until_exceeded.rb @@ -1,7 +1,5 @@ module IceCube - # An exception for when an until date on a Rule is passed class UntilExceeded < StopIteration end - end diff --git a/lib/ice_cube/flexible_hash.rb b/lib/ice_cube/flexible_hash.rb index 6905a839..9cd3bf82 100644 --- a/lib/ice_cube/flexible_hash.rb +++ b/lib/ice_cube/flexible_hash.rb @@ -1,13 +1,10 @@ require 'delegate' module IceCube - # Find keys by symbol or string without symbolizing user input # Due to the serialization format of ice_cube, this limited implementation # is entirely sufficient - class FlexibleHash < SimpleDelegator - def [](key) key = _match_key(key) super @@ -26,7 +23,8 @@ def delete(key) private def _match_key(key) - return key if __getobj__.has_key? key + return key if __getobj__.key? key + if Symbol == key.class __getobj__.keys.detect { |k| return k if k == key.to_s } elsif String == key.class @@ -34,7 +32,5 @@ def _match_key(key) end key end - end - end diff --git a/lib/ice_cube/i18n.rb b/lib/ice_cube/i18n.rb index 39f15c17..4c438478 100644 --- a/lib/ice_cube/i18n.rb +++ b/lib/ice_cube/i18n.rb @@ -2,7 +2,6 @@ module IceCube module I18n - LOCALES_PATH = File.expand_path(File.join('..', '..', '..', 'config', 'locales'), __FILE__) def self.t(*args) diff --git a/lib/ice_cube/input_alignment.rb b/lib/ice_cube/input_alignment.rb index 2fecb5fb..a01cab6c 100644 --- a/lib/ice_cube/input_alignment.rb +++ b/lib/ice_cube/input_alignment.rb @@ -1,6 +1,5 @@ module IceCube class InputAlignment - def initialize(rule, value, rule_part) @rule = rule @value = value @@ -9,8 +8,8 @@ def initialize(rule, value, rule_part) attr_reader :rule, :value, :rule_part - def verify(freq, options={}, &block) - @rule.validations[:interval] or return + def verify(freq, options = {}, &block) + @rule.validations[:interval] || return case @rule when DailyRule @@ -29,20 +28,20 @@ def interval_validation end def interval_value - @interval_value ||= (rule_part == :interval) ? value : interval_validation.interval + @interval_value ||= rule_part == :interval ? value : interval_validation.interval end def fixed_validations - @fixed_validations ||= @rule.validations.values.flatten.select { |v| + @fixed_validations ||= @rule.validations.values.flatten.select do |v| interval_type = (v.type == :wday ? :day : v.type) v.class < Validations::FixedValue && interval_type == rule.base_interval_validation.type - } + end end def verify_freq_alignment(freq) - interval_validation.type == freq or return - (last_validation = fixed_validations.min_by(&:value)) or return + (interval_validation.type == freq) || return + (last_validation = fixed_validations.min_by(&:value)) || return alignment = (value - last_validation.value) % interval_validation.interval return if alignment.zero? @@ -74,16 +73,15 @@ def verify_wday_alignment(freq) return if interval_value == 1 if freq == :wday - return if (interval_value % 7).zero? - return if Array(@rule.validations[:day]).empty? + return if (interval_value % 7).zero? || Array(@rule.validations[:day]).empty? + message = "day can only be used with multiples of interval(7)" else - (fixed_validation = fixed_validations.first) or return + (fixed_validation = fixed_validations.first) || return message = "#{fixed_validation.key} can only be used with interval(1)" end yield ArgumentError.new(message) end - end end diff --git a/lib/ice_cube/null_i18n.rb b/lib/ice_cube/null_i18n.rb index 35b5e0b8..0837147c 100644 --- a/lib/ice_cube/null_i18n.rb +++ b/lib/ice_cube/null_i18n.rb @@ -18,12 +18,14 @@ def self.t(key, options = {}) end else return base unless base.include?('%{') + base % options end end def self.l(date_or_time, options = {}) return date_or_time.strftime(options[:format]) if options[:format] + date_or_time.strftime(t('ice_cube.date.formats.default')) end diff --git a/lib/ice_cube/occurrence.rb b/lib/ice_cube/occurrence.rb index 6ec9cd73..958a93ff 100644 --- a/lib/ice_cube/occurrence.rb +++ b/lib/ice_cube/occurrence.rb @@ -1,7 +1,6 @@ require 'delegate' module IceCube - # Wraps start_time and end_time in a single concept concerning the duration. # This delegates to the enclosed start_time so it behaves like a normal Time # in almost all situations, however: @@ -30,7 +29,7 @@ def self.name alias first start_time alias last end_time - def initialize(start_time, end_time=nil) + def initialize(start_time, end_time = nil) @start_time = start_time @end_time = end_time || start_time __setobj__ @start_time @@ -47,7 +46,7 @@ def <=>(other) def is_a?(klass) klass == ::Time || super end - alias_method :kind_of?, :is_a? + alias kind_of? is_a? def intersects?(other) return cover?(other) unless other.is_a?(Occurrence) || other.is_a?(Range) @@ -63,7 +62,7 @@ def intersects?(other) def cover?(other) to_range.cover?(other) end - alias_method :include?, :cover? + alias include? cover? def comparable_time start_time @@ -85,7 +84,7 @@ def to_time # Optional format argument (e.g. :long, :short) supports Rails # time formats and is only used when ActiveSupport is available. # - def to_s(format=nil) + def to_s(format = nil) if format && to_time.public_method(:to_s).arity != 0 t0, t1 = start_time.to_s(format), end_time.to_s(format) else diff --git a/lib/ice_cube/parsers/hash_parser.rb b/lib/ice_cube/parsers/hash_parser.rb index ea577544..d6337bd4 100644 --- a/lib/ice_cube/parsers/hash_parser.rb +++ b/lib/ice_cube/parsers/hash_parser.rb @@ -1,6 +1,5 @@ module IceCube class HashParser - attr_reader :hash def initialize(original_hash) @@ -26,13 +25,13 @@ def normalize_keys(hash) data = IceCube::FlexibleHash.new(hash.dup) if (start_date = data.delete(:start_date)) - warn "IceCube: :start_date is deprecated, please use :start_time at: #{ caller[0] }" + warn "IceCube: :start_date is deprecated, please use :start_time at: #{caller[0]}" data[:start_time] = start_date end - {:rdates => :rtimes, :exdates => :extimes}.each do |old_key, new_key| + { rdates: :rtimes, exdates: :extimes }.each do |old_key, new_key| if (times = data.delete(old_key)) - warn "IceCube: :#{old_key} is deprecated, please use :#{new_key} at: #{ caller[0] }" + warn "IceCube: :#{old_key} is deprecated, please use :#{new_key} at: #{caller[0]}" (data[new_key] ||= []).concat times end end @@ -42,16 +41,19 @@ def normalize_keys(hash) def apply_duration(schedule, data) return unless data[:duration] + schedule.duration = data[:duration].to_i end def apply_end_time(schedule, data) return unless data[:end_time] + schedule.end_time = parse_time(data[:end_time]) end def apply_rrules(schedule, data) return unless data[:rrules] + data[:rrules].each do |h| rrule = h.is_a?(IceCube::Rule) ? h : IceCube::Rule.from_hash(h) @@ -61,7 +63,8 @@ def apply_rrules(schedule, data) def apply_exrules(schedule, data) return unless data[:exrules] - warn "IceCube: :exrules is deprecated, and will be removed in a future release. at: #{ caller[0] }" + + warn "IceCube: :exrules is deprecated, and will be removed in a future release. at: #{caller[0]}" data[:exrules].each do |h| rrule = h.is_a?(IceCube::Rule) ? h : IceCube::Rule.from_hash(h) @@ -71,6 +74,7 @@ def apply_exrules(schedule, data) def apply_rtimes(schedule, data) return unless data[:rtimes] + data[:rtimes].each do |t| schedule.add_recurrence_time TimeUtil.deserialize_time(t) end @@ -78,6 +82,7 @@ def apply_rtimes(schedule, data) def apply_extimes(schedule, data) return unless data[:extimes] + data[:extimes].each do |t| schedule.add_exception_time TimeUtil.deserialize_time(t) end @@ -86,6 +91,5 @@ def apply_extimes(schedule, data) def parse_time(time) TimeUtil.deserialize_time(time) end - end end diff --git a/lib/ice_cube/parsers/ical_parser.rb b/lib/ice_cube/parsers/ical_parser.rb index c6b91a1a..dce83624 100644 --- a/lib/ice_cube/parsers/ical_parser.rb +++ b/lib/ice_cube/parsers/ical_parser.rb @@ -1,6 +1,6 @@ module IceCube class IcalParser - def self.schedule_from_ical(ical_string, options = {}) + def self.schedule_from_ical(ical_string, _options = {}) data = {} ical_string.each_line do |line| (property, value) = line.split(':') @@ -30,11 +30,12 @@ def self.rule_from_ical(ical) raise ArgumentError, 'empty ical rule' if ical.nil? validations = {} - params = {validations: validations, interval: 1} + params = { validations: validations, interval: 1 } ical.split(';').each do |rule| (name, value) = rule.split('=') raise ArgumentError, "Invalid iCal rule component" if value.nil? + value.strip! case name when 'FREQ' @@ -58,7 +59,7 @@ def self.rule_from_ical(ical) days = [] value.split(',').each do |expr| day = TimeUtil.ical_day_to_symbol(expr.strip[-2..-1]) - if expr.strip.length > 2 # day with occurence + if expr.strip.length > 2 # day with occurence occ = expr[0..-3].to_i dows[day].nil? ? dows[day] = [occ] : dows[day].push(occ) days.delete(TimeUtil.sym_to_wday(day)) diff --git a/lib/ice_cube/parsers/yaml_parser.rb b/lib/ice_cube/parsers/yaml_parser.rb index 151d28e1..ca033381 100644 --- a/lib/ice_cube/parsers/yaml_parser.rb +++ b/lib/ice_cube/parsers/yaml_parser.rb @@ -2,18 +2,16 @@ module IceCube class YamlParser < HashParser - SERIALIZED_START = /start_(?:time|date): .+(?(?:-|\+)\d{2}:\d{2})$/ attr_reader :hash def initialize(yaml) - @hash = YAML::load(yaml) + @hash = YAML.load(yaml) yaml.match SERIALIZED_START do |match| start_time = hash[:start_time] || hash[:start_date] TimeUtil.restore_deserialized_offset start_time, match[:tz] end end - end end diff --git a/lib/ice_cube/rule.rb b/lib/ice_cube/rule.rb index c8cd992c..0b696b82 100644 --- a/lib/ice_cube/rule.rb +++ b/lib/ice_cube/rule.rb @@ -1,18 +1,15 @@ require 'yaml' module IceCube - class Rule - - INTERVAL_TYPES = [ - :secondly, :minutely, :hourly, - :daily, :weekly, :monthly, :yearly - ] + INTERVAL_TYPES = %i[ + secondly minutely hourly + daily weekly monthly yearly + ].freeze attr_reader :uses - def reset - end + def reset; end # Is this a terminating schedule? def terminating? @@ -21,6 +18,7 @@ def terminating? def ==(other) return false unless other.is_a? Rule + hash == other.hash end @@ -39,27 +37,25 @@ def self.from_ical(ical) # Yaml implementation def to_yaml(*args) - YAML::dump(to_hash, *args) + YAML.dump(to_hash, *args) end # From yaml def self.from_yaml(yaml) - from_hash YAML::load(yaml) + from_hash YAML.load(yaml) end def to_hash raise MethodNotImplemented, "Expected to be overridden by subclasses" end - def next_time(time, schedule, closing_time) - end + def next_time(time, schedule, closing_time); end def on?(time, schedule) next_time(time, schedule, time).to_i == time.to_i end class << self - # Convert from a hash and create a rule def from_hash(original_hash) hash = IceCube::FlexibleHash.new original_hash @@ -76,7 +72,7 @@ def from_hash(original_hash) rule = IceCube::Rule.send(interval_type, hash[:interval] || 1) - if match[1] == "Weekly" + if match[1] == 'Weekly' rule.interval(hash[:interval] || 1, TimeUtil.wday_to_sym(hash[:week_start] || 0)) end @@ -101,12 +97,10 @@ def apply_validation(rule, name, args) args.is_a?(Array) ? rule.send(name, *args) : rule.send(name, args) end - end # Convenience methods for creating Rules class << self - # Secondly Rule def secondly(interval = 1) SecondlyRule.new(interval) @@ -141,9 +135,6 @@ def monthly(interval = 1) def yearly(interval = 1) YearlyRule.new(interval) end - end - end - end diff --git a/lib/ice_cube/rules/daily_rule.rb b/lib/ice_cube/rules/daily_rule.rb index e5b77dac..ed5014f2 100644 --- a/lib/ice_cube/rules/daily_rule.rb +++ b/lib/ice_cube/rules/daily_rule.rb @@ -1,7 +1,5 @@ module IceCube - class DailyRule < ValidatedRule - include Validations::HourOfDay include Validations::MinuteOfHour include Validations::SecondOfMinute @@ -19,7 +17,5 @@ def initialize(interval = 1) schedule_lock(:hour, :min, :sec) reset end - end - end diff --git a/lib/ice_cube/rules/hourly_rule.rb b/lib/ice_cube/rules/hourly_rule.rb index a4e0ba1b..638104e1 100644 --- a/lib/ice_cube/rules/hourly_rule.rb +++ b/lib/ice_cube/rules/hourly_rule.rb @@ -1,7 +1,5 @@ module IceCube - class HourlyRule < ValidatedRule - include Validations::HourOfDay include Validations::MinuteOfHour include Validations::SecondOfMinute @@ -10,7 +8,6 @@ class HourlyRule < ValidatedRule include Validations::Day include Validations::MonthOfYear include Validations::DayOfYear - include Validations::HourlyInterval def initialize(interval = 1) @@ -19,7 +16,5 @@ def initialize(interval = 1) schedule_lock(:min, :sec) reset end - end - end diff --git a/lib/ice_cube/rules/minutely_rule.rb b/lib/ice_cube/rules/minutely_rule.rb index 640e1ab7..8d415bc3 100644 --- a/lib/ice_cube/rules/minutely_rule.rb +++ b/lib/ice_cube/rules/minutely_rule.rb @@ -1,7 +1,5 @@ module IceCube - class MinutelyRule < ValidatedRule - include Validations::HourOfDay include Validations::MinuteOfHour include Validations::SecondOfMinute @@ -10,7 +8,6 @@ class MinutelyRule < ValidatedRule include Validations::Day include Validations::MonthOfYear include Validations::DayOfYear - include Validations::MinutelyInterval def initialize(interval = 1) @@ -19,7 +16,5 @@ def initialize(interval = 1) schedule_lock(:sec) reset end - end - end diff --git a/lib/ice_cube/rules/monthly_rule.rb b/lib/ice_cube/rules/monthly_rule.rb index 3e1307fb..6c5d4316 100644 --- a/lib/ice_cube/rules/monthly_rule.rb +++ b/lib/ice_cube/rules/monthly_rule.rb @@ -1,7 +1,5 @@ module IceCube - class MonthlyRule < ValidatedRule - include Validations::HourOfDay include Validations::MinuteOfHour include Validations::SecondOfMinute @@ -10,7 +8,6 @@ class MonthlyRule < ValidatedRule include Validations::Day include Validations::MonthOfYear # include Validations::DayOfYear # n/a - include Validations::MonthlyInterval def initialize(interval = 1) @@ -19,7 +16,5 @@ def initialize(interval = 1) schedule_lock(:day, :hour, :min, :sec) reset end - end - end diff --git a/lib/ice_cube/rules/secondly_rule.rb b/lib/ice_cube/rules/secondly_rule.rb index ecd62532..22b78055 100644 --- a/lib/ice_cube/rules/secondly_rule.rb +++ b/lib/ice_cube/rules/secondly_rule.rb @@ -1,7 +1,5 @@ module IceCube - class SecondlyRule < ValidatedRule - include Validations::HourOfDay include Validations::MinuteOfHour include Validations::SecondOfMinute @@ -10,7 +8,6 @@ class SecondlyRule < ValidatedRule include Validations::Day include Validations::MonthOfYear include Validations::DayOfYear - include Validations::SecondlyInterval def initialize(interval = 1) @@ -18,7 +15,5 @@ def initialize(interval = 1) interval(interval) reset end - end - end diff --git a/lib/ice_cube/rules/weekly_rule.rb b/lib/ice_cube/rules/weekly_rule.rb index dd39f2b3..d64ed4a1 100644 --- a/lib/ice_cube/rules/weekly_rule.rb +++ b/lib/ice_cube/rules/weekly_rule.rb @@ -1,7 +1,5 @@ module IceCube - class WeeklyRule < ValidatedRule - include Validations::HourOfDay include Validations::MinuteOfHour include Validations::SecondOfMinute @@ -10,7 +8,6 @@ class WeeklyRule < ValidatedRule include Validations::Day include Validations::MonthOfYear # include Validations::DayOfYear # n/a - include Validations::WeeklyInterval attr_reader :week_start @@ -57,7 +54,5 @@ def wday_offset(step_time, start_time) days + interval - step_wday + min_wday end - end - end diff --git a/lib/ice_cube/rules/yearly_rule.rb b/lib/ice_cube/rules/yearly_rule.rb index 3a18b0a6..4696a352 100644 --- a/lib/ice_cube/rules/yearly_rule.rb +++ b/lib/ice_cube/rules/yearly_rule.rb @@ -1,7 +1,5 @@ module IceCube - class YearlyRule < ValidatedRule - include Validations::HourOfDay include Validations::MinuteOfHour include Validations::SecondOfMinute @@ -10,7 +8,6 @@ class YearlyRule < ValidatedRule include Validations::Day include Validations::MonthOfYear include Validations::DayOfYear - include Validations::YearlyInterval def initialize(interval = 1) @@ -19,7 +16,5 @@ def initialize(interval = 1) schedule_lock(:month, :day, :hour, :min, :sec) reset end - end - end diff --git a/lib/ice_cube/schedule.rb b/lib/ice_cube/schedule.rb index 9f930cb3..62618f1f 100644 --- a/lib/ice_cube/schedule.rb +++ b/lib/ice_cube/schedule.rb @@ -1,9 +1,7 @@ require 'yaml' module IceCube - class Schedule - extend Deprecated # Get the start time @@ -47,31 +45,34 @@ def duration=(seconds) # Add a recurrence time to the schedule def add_recurrence_time(time) return if time.nil? + rule = SingleOccurrenceRule.new(time) add_recurrence_rule rule time end - alias :rtime :add_recurrence_time + alias rtime add_recurrence_time deprecated_alias :rdate, :rtime deprecated_alias :add_recurrence_date, :add_recurrence_time # Add an exception time to the schedule def add_exception_time(time) return if time.nil? + rule = SingleOccurrenceRule.new(time) add_exception_rule rule time end - alias :extime :add_exception_time + alias extime add_exception_time deprecated_alias :exdate, :extime deprecated_alias :add_exception_date, :add_exception_time # Add a recurrence rule to the schedule def add_recurrence_rule(rule) return if rule.nil? + @all_recurrence_rules << rule unless @all_recurrence_rules.include?(rule) end - alias :rrule :add_recurrence_rule + alias rrule add_recurrence_rule # Remove a recurrence rule def remove_recurrence_rule(rule) @@ -82,9 +83,10 @@ def remove_recurrence_rule(rule) # Add an exception rule to the schedule def add_exception_rule(rule) return if rule.nil? + @all_exception_rules << rule unless @all_exception_rules.include?(rule) end - alias :exrule :add_exception_rule + alias exrule add_exception_rule # Remove an exception rule def remove_exception_rule(rule) @@ -96,19 +98,19 @@ def remove_exception_rule(rule) def recurrence_rules @all_recurrence_rules.reject { |r| r.is_a?(SingleOccurrenceRule) } end - alias :rrules :recurrence_rules + alias rrules recurrence_rules # Get the exception rules def exception_rules @all_exception_rules.reject { |r| r.is_a?(SingleOccurrenceRule) } end - alias :exrules :exception_rules + alias exrules exception_rules # Get the recurrence times that are on the schedule def recurrence_times @all_recurrence_rules.select { |r| r.is_a?(SingleOccurrenceRule) }.map(&:time) end - alias :rtimes :recurrence_times + alias rtimes recurrence_times deprecated_alias :rdates, :rtimes deprecated_alias :recurrence_dates, :recurrence_times @@ -120,7 +122,7 @@ def remove_recurrence_time(time) end time if found end - alias :remove_rtime :remove_recurrence_time + alias remove_rtime remove_recurrence_time deprecated_alias :remove_recurrence_date, :remove_recurrence_time deprecated_alias :remove_rdate, :remove_rtime @@ -128,7 +130,7 @@ def remove_recurrence_time(time) def exception_times @all_exception_rules.select { |r| r.is_a?(SingleOccurrenceRule) }.map(&:time) end - alias :extimes :exception_times + alias extimes exception_times deprecated_alias :exdates, :extimes deprecated_alias :exception_dates, :exception_times @@ -140,7 +142,7 @@ def remove_exception_time(time) end time if found end - alias :remove_extime :remove_exception_time + alias remove_extime remove_exception_time deprecated_alias :remove_exception_date, :remove_exception_time deprecated_alias :remove_exdate, :remove_extime @@ -183,17 +185,19 @@ def next_occurrence(from = nil, options = {}) # The previous occurrence from a given time def previous_occurrence(from) - from = TimeUtil.match_zone(from, start_time) or raise ArgumentError, "Time required, got #{from.inspect}" + (from = TimeUtil.match_zone(from, start_time)) || raise(ArgumentError, "Time required, got #{from.inspect}") return nil if from <= start_time + enumerate_occurrences(start_time, from - 1).to_a.last end # The previous n occurrences before a given time def previous_occurrences(num, from) - from = TimeUtil.match_zone(from, start_time) or raise ArgumentError, "Time required, got #{from.inspect}" + (from = TimeUtil.match_zone(from, start_time)) || raise(ArgumentError, "Time required, got #{from.inspect}") return [] if from <= start_time + a = enumerate_occurrences(start_time, from - 1).to_a - a.size > num ? a[-1*num,a.size] : a + a.size > num ? a[-1 * num, a.size] : a end # The remaining occurrences (same requirements as all_occurrences) @@ -228,7 +232,7 @@ def occurs_between?(begin_time, closing_time, options = {}) # occurrences at the end of the range since none of their duration # intersects the range. def occurring_between?(opening_time, closing_time) - occurs_between?(opening_time, closing_time, :spans => true) + occurs_between?(opening_time, closing_time, spans: true) end # Return a boolean indicating if an occurrence falls on a certain date @@ -241,9 +245,10 @@ def occurs_on?(date) # Determine if the schedule is occurring at a given time def occurring_at?(time) - time = TimeUtil.match_zone(time, start_time) or raise ArgumentError, "Time required, got #{time.inspect}" + (time = TimeUtil.match_zone(time, start_time)) || raise(ArgumentError, "Time required, got #{time.inspect}") if duration > 0 return false if exception_time?(time) + occurs_between?(time - duration + 1, time) else occurs_at?(time) @@ -259,6 +264,7 @@ def conflicts_with?(other_schedule, closing_time = nil) unless terminating? || other_schedule.terminating? || closing_time raise ArgumentError, "One or both schedules must be terminating to use #conflicts_with?" end + # Pick the terminating schedule, and other schedule # No need to reverse if terminating? or there is a closing time terminating_schedule = self @@ -314,7 +320,7 @@ def to_s pieces = [] rd = recurrence_times_with_start_time - extimes pieces.concat rd.sort.map { |t| IceCube::I18n.l(t, format: IceCube.to_s_time_format) } - pieces.concat rrules.map { |t| t.to_s } + pieces.concat rrules.map(&:to_s) pieces.concat exrules.map { |t| IceCube::I18n.t('ice_cube.not', target: t.to_s) } pieces.concat extimes.sort.map { |t| target = IceCube::I18n.l(t, format: IceCube.to_s_time_format) @@ -330,7 +336,7 @@ def to_ical(force_utc = false) pieces.concat recurrence_rules.map { |r| "RRULE:#{r.to_ical}" } pieces.concat exception_rules.map { |r| "EXRULE:#{r.to_ical}" } pieces.concat recurrence_times_without_start_time.map { |t| "RDATE#{IcalBuilder.ical_format(t, force_utc)}" } - pieces.concat exception_times.map { |t| "EXDATE#{IcalBuilder.ical_format(t, force_utc)}" } + pieces.concat exception_times.map { |t| "EXDATE#{IcalBuilder.ical_format(t, force_utc)}" } pieces << "DTEND#{IcalBuilder.ical_format(end_time, force_utc)}" if end_time pieces.join("\n") end @@ -371,7 +377,7 @@ def to_hash end data end - alias_method :to_h, :to_hash + alias to_h to_hash # Load the schedule from a hash def self.from_hash(original_hash, options = {}) @@ -396,17 +402,19 @@ def hash end def eql?(other) - self.hash == other.hash + hash == other.hash end alias == eql? def self.dump(schedule) - return schedule if schedule.nil? || schedule == "" + return schedule if schedule.nil? || schedule == '' + schedule.to_yaml end def self.load(yaml) - return yaml if yaml.nil? || yaml == "" + return yaml if yaml.nil? || yaml == '' + from_yaml(yaml) end @@ -435,7 +443,8 @@ def enumerate_occurrences(opening_time, closing_time = nil, options = {}) loop do break unless (t0 = next_time(t1, closing_time)) break if closing_time && t0 > closing_time - if (spans ? (t0.end_time > opening_time) : (t0 >= opening_time)) + + if spans ? (t0.end_time > opening_time) : (t0 >= opening_time) yielder << (block_given? ? yield(t0) : t0) end t1 = t0 + 1 @@ -456,6 +465,7 @@ def next_time(time, closing_time) end break unless min_time next (time = min_time + 1) if exception_time?(min_time) + break Occurrence.new(min_time, min_time + duration) end end @@ -464,7 +474,7 @@ def next_time(time, closing_time) # If we have rules with counts, we need to walk from the beginning of time def full_required? @all_recurrence_rules.any?(&:full_required?) || - @all_exception_rules.any?(&:full_required?) + @all_exception_rules.any?(&:full_required?) end # Return a boolean indicating whether or not a specific time @@ -477,6 +487,7 @@ def exception_time?(time) def require_terminating_rules return true if terminating? + method_name = caller[0].split(' ').last raise ArgumentError, "All recurrence rules must specify .until or .count to use #{method_name}" end @@ -504,7 +515,5 @@ def recurrence_rules_with_implicit_start_occurrence @all_recurrence_rules end end - end - end diff --git a/lib/ice_cube/single_occurrence_rule.rb b/lib/ice_cube/single_occurrence_rule.rb index 9232e8a7..a693dbcf 100644 --- a/lib/ice_cube/single_occurrence_rule.rb +++ b/lib/ice_cube/single_occurrence_rule.rb @@ -1,7 +1,5 @@ module IceCube - class SingleOccurrenceRule < Rule - attr_reader :time def initialize(time) @@ -20,13 +18,11 @@ def next_time(t, _, closing_time) end def to_hash - { :time => time } + { time: time } end def full_required? false end - end - end diff --git a/lib/ice_cube/time_util.rb b/lib/ice_cube/time_util.rb index ff43399e..abc81114 100644 --- a/lib/ice_cube/time_util.rb +++ b/lib/ice_cube/time_util.rb @@ -3,29 +3,28 @@ module IceCube module TimeUtil - extend Deprecated DAYS = { - :sunday => 0, :monday => 1, :tuesday => 2, :wednesday => 3, - :thursday => 4, :friday => 5, :saturday => 6 - } + sunday: 0, monday: 1, tuesday: 2, wednesday: 3, + thursday: 4, friday: 5, saturday: 6 + }.freeze ICAL_DAYS = { 'SU' => :sunday, 'MO' => :monday, 'TU' => :tuesday, 'WE' => :wednesday, 'TH' => :thursday, 'FR' => :friday, 'SA' => :saturday - } + }.freeze MONTHS = { - :january => 1, :february => 2, :march => 3, :april => 4, :may => 5, - :june => 6, :july => 7, :august => 8, :september => 9, :october => 10, - :november => 11, :december => 12 - } + january: 1, february: 2, march: 3, april: 4, may: 5, + june: 6, july: 7, august: 8, september: 9, october: 10, + november: 11, december: 12 + }.freeze - CLOCK_VALUES = [:year, :month, :day, :hour, :min, :sec] + CLOCK_VALUES = %I[year month day hour min sec].freeze # Provides a Time.now without the usec, in the reference zone or utc offset - def self.now(reference=Time.now) + def self.now(reference = Time.now) match_zone(Time.at(Time.now.to_i), reference) end @@ -43,6 +42,7 @@ def self.build_in_zone(args, reference) def self.match_zone(input_time, reference) return unless time = ensure_time(input_time, reference) + time = if reference.respond_to? :time_zone time.in_time_zone(reference.time_zone) else @@ -54,14 +54,14 @@ def self.match_zone(input_time, reference) time.getlocal(reference.utc_offset) end end - (Date === input_time) ? beginning_of_date(time, reference) : time + Date === input_time ? beginning_of_date(time, reference) : time end # Ensure that this is either nil, or a time def self.ensure_time(time, reference = nil, date_eod = false) case time when DateTime - warn "IceCube: DateTime support is deprecated (please use Time) at: #{ caller[2] }" + warn "IceCube: DateTime support is deprecated (please use Time) at: #{caller[2]}" Time.local(time.year, time.month, time.day, time.hour, time.min, time.sec) when Date if date_eod @@ -83,7 +83,7 @@ def self.ensure_date(date) case date when Date then date else - return Date.new(date.year, date.month, date.day) + Date.new(date.year, date.month, date.day) end end @@ -92,7 +92,7 @@ def self.serialize_time(time) case time when Time, Date if time.respond_to?(:time_zone) - {:time => time.utc, :zone => time.time_zone.name} + { time: time.utc, zone: time.time_zone.name } else time end @@ -134,17 +134,18 @@ def self.hash(time) def self.restore_deserialized_offset(time, orig_offset_str) return time if time.respond_to?(:time_zone) || time.getlocal(orig_offset_str).utc_offset == time.utc_offset - warn "IceCube: parsed Time from nonlocal TZ. Use ActiveSupport to fix DST at: #{ caller[0] }" + + warn "IceCube: parsed Time from nonlocal TZ. Use ActiveSupport to fix DST at: #{caller[0]}" time.localtime(orig_offset_str) end # Get the beginning of a date - def self.beginning_of_date(date, reference=Time.now) + def self.beginning_of_date(date, reference = Time.now) build_in_zone([date.year, date.month, date.day, 0, 0, 0], reference) end # Get the end of a date - def self.end_of_date(date, reference=Time.now) + def self.end_of_date(date, reference = Time.now) build_in_zone([date.year, date.month, date.day, 23, 59, 59], reference) end @@ -170,7 +171,8 @@ def self.sym_to_wday(sym) # Convert wday number to day symbol def self.wday_to_sym(wday) - return wday if DAYS.keys.include? wday + return wday if DAYS.key? wday + DAYS.invert.fetch(wday) do |i| raise ArgumentError, "Expecting Integer value for weekday. " \ "No such wday number: #{i.inspect}" @@ -186,12 +188,13 @@ def self.normalize_wday(wday, week_start) def self.ical_day_to_symbol(str) day = ICAL_DAYS[str] raise ArgumentError, "Invalid day: #{str}" if day.nil? + day end # Return the count of the number of times wday appears in the month, # and which of those time falls on - def self.which_occurrence_in_month(time, wday) + def self.which_occurrence_in_month(time, _wday) first_occurrence = ((7 - Time.utc(time.year, time.month, 1).wday) + time.wday) % 7 + 1 this_weekday_in_month_count = ((days_in_month(time) - first_occurrence + 1) / 7.0).ceil nth_occurrence_of_weekday = (time.mday - first_occurrence) / 7 + 1 @@ -270,7 +273,6 @@ def self.subsec(time) # A utility class for safely moving time around class TimeWrapper - def initialize(time, dst_adjust = true) @dst_adjust = dst_adjust @base = time @@ -284,6 +286,7 @@ def initialize(time, dst_adjust = true) # Get the wrapped time back in its original zone & format def to_time return @time unless @dst_adjust + parts = @time.year, @time.month, @time.day, @time.hour, @time.min, @time.sec + @time.subsec TimeUtil.build_in_zone(parts, @base) end @@ -302,11 +305,12 @@ def add(type, val) end # Clear everything below a certain type - CLEAR_ORDER = [:sec, :min, :hour, :day, :month, :year] + CLEAR_ORDER = %i[sec min hour day month year].freeze def clear_below(type) type = :day if type == :wday CLEAR_ORDER.each do |ptype| break if ptype == type + send :"clear_#{ptype}" end end @@ -320,7 +324,7 @@ def min=(value) end def sec=(value) - @time += (value) - (@time.sec) + @time += value - @time.sec end def clear_sec @@ -343,13 +347,9 @@ def clear_day # Clear to january 1st def clear_month @time -= ONE_DAY - until @time.month == 12 - @time -= TimeUtil.days_in_month(@time) * ONE_DAY - end + @time -= TimeUtil.days_in_month(@time) * ONE_DAY until @time.month == 12 @time += ONE_DAY end - end - end end diff --git a/lib/ice_cube/validated_rule.rb b/lib/ice_cube/validated_rule.rb index 69830fab..a6a14bda 100644 --- a/lib/ice_cube/validated_rule.rb +++ b/lib/ice_cube/validated_rule.rb @@ -1,9 +1,7 @@ require 'ice_cube/input_alignment' module IceCube - class ValidatedRule < Rule - include Validations::ScheduleLock include Validations::Count @@ -15,18 +13,18 @@ class ValidatedRule < Rule # * base values by cardinality (n = 60, 60, 31, 24, 12, 7) # * locks by cardinality (n = 365, 60, 60, 31, 24, 12, 7) # * interval multiplier - VALIDATION_ORDER = [ - :year, :month, :day, :wday, :hour, :min, :sec, :count, :until, - :base_sec, :base_min, :base_day, :base_hour, :base_month, :base_wday, - :day_of_year, :second_of_minute, :minute_of_hour, :day_of_month, - :hour_of_day, :month_of_year, :day_of_week, - :interval - ] + VALIDATION_ORDER = %i[ + year month day wday hour min sec count until + base_sec base_min base_day base_hour base_month base_wday + day_of_year second_of_minute minute_of_hour day_of_month + hour_of_day month_of_year day_of_week + interval + ].freeze attr_reader :validations - def initialize(interval = 1) - @validations = Hash.new + def initialize(_interval = 1) + @validations = {} end # Reset the uses on the rule to 0 @@ -59,7 +57,7 @@ def next_time(time, start_time, closing_time) @time end - def realign(opening_time, start_time) + def realign(_opening_time, start_time) start_time end @@ -123,6 +121,7 @@ def clobber_base_validations(*types) def normalized_interval(interval) int = interval.to_i raise ArgumentError, "'#{interval}' is not a valid input for interval. Please pass a postive integer." unless int > 0 + int end @@ -146,6 +145,7 @@ def validation_accepts_or_updates_time?(validations_for_type) res = validations_for_type.each_with_object([]) do |validation, offsets| r = validation.validate(@time, @start_time) return true if r.nil? || r == 0 + offsets << r end shift_time_by_validation(res, validations_for_type.first) @@ -154,6 +154,7 @@ def validation_accepts_or_updates_time?(validations_for_type) def shift_time_by_validation(res, validation) return unless (interval = res.min) + wrapper = TimeUtil::TimeWrapper.new(@time, validation.dst_adjust?) wrapper.add(validation.type, interval) wrapper.clear_below(validation.type) @@ -183,7 +184,5 @@ def verify_alignment(value, freq, rule_part) yield error end end - end - end diff --git a/lib/ice_cube/validations/count.rb b/lib/ice_cube/validations/count.rb index b9e136c3..0a597fee 100644 --- a/lib/ice_cube/validations/count.rb +++ b/lib/ice_cube/validations/count.rb @@ -1,7 +1,5 @@ module IceCube - module Validations::Count - # Value reader for limit def occurrence_count (arr = @validations[:count]) && (val = arr[0]) && val.count @@ -11,12 +9,12 @@ def count(max) unless max.nil? || max.is_a?(Integer) raise ArgumentError, "Expecting Integer or nil value for count, got #{max.inspect}" end + replace_validations_for(:count, max && [Validation.new(max, self)]) self end class Validation - attr_reader :rule, :count def initialize(count, rule) @@ -52,9 +50,6 @@ def build_ical(builder) count = segments.first IceCube::I18n.t('ice_cube.times', count: count) end - end - end - end diff --git a/lib/ice_cube/validations/daily_interval.rb b/lib/ice_cube/validations/daily_interval.rb index 528c56cf..210408fa 100644 --- a/lib/ice_cube/validations/daily_interval.rb +++ b/lib/ice_cube/validations/daily_interval.rb @@ -1,7 +1,5 @@ module IceCube - module Validations::DailyInterval - # Add a new interval validation def interval(interval) interval = normalized_interval(interval) @@ -15,7 +13,6 @@ def interval(interval) end class Validation - attr_reader :interval def initialize(interval) @@ -50,9 +47,6 @@ def build_ical(builder) builder['FREQ'] << 'DAILY' builder['INTERVAL'] << interval unless interval == 1 end - end - end - end diff --git a/lib/ice_cube/validations/day.rb b/lib/ice_cube/validations/day.rb index 6079ed6f..d148d6ee 100644 --- a/lib/ice_cube/validations/day.rb +++ b/lib/ice_cube/validations/day.rb @@ -1,14 +1,14 @@ module IceCube - module Validations::Day - def day(*days) days = days.flatten return self if days.empty? + days.flatten.each do |day| unless day.is_a?(Integer) || day.is_a?(Symbol) raise ArgumentError, "expecting Integer or Symbol value for day, got #{day.inspect}" end + day = TimeUtil.sym_to_wday(day) verify_alignment(day, :wday, :day) { |error| raise error } @@ -19,9 +19,8 @@ def day(*days) end class Validation < Validations::FixedValue - attr_reader :day - alias :value :day + alias value day def initialize(day) @day = day @@ -64,14 +63,11 @@ def build_ical(builder) elsif validation_days == (1..5).to_a IceCube::I18n.t('ice_cube.on_weekdays') else - day_names = ->(d){ "#{IceCube::I18n.t("ice_cube.days_on")[d]}" } + day_names = ->(d) { (IceCube::I18n.t('ice_cube.days_on')[d]).to_s } segments = validation_days.map(&day_names) IceCube::I18n.t('ice_cube.on_days', days: StringBuilder.sentence(segments)) end end - end - end - end diff --git a/lib/ice_cube/validations/day_of_month.rb b/lib/ice_cube/validations/day_of_month.rb index 88496ed4..3939fef9 100644 --- a/lib/ice_cube/validations/day_of_month.rb +++ b/lib/ice_cube/validations/day_of_month.rb @@ -1,12 +1,11 @@ module IceCube - module Validations::DayOfMonth - def day_of_month(*days) days.flatten.each do |day| unless day.is_a?(Integer) raise ArgumentError, "expecting Integer value for day, got #{day.inspect}" end + verify_alignment(day, :day, :day_of_month) { |error| raise error } validations_for(:day_of_month) << Validation.new(day) end @@ -15,9 +14,8 @@ def day_of_month(*days) end class Validation < Validations::FixedValue - attr_reader :day - alias :value :day + alias value day def initialize(day) @day = day @@ -52,9 +50,6 @@ def build_ical(builder) str = IceCube::I18n.t('ice_cube.days_of_month', count: entries.size, segments: sentence) IceCube::I18n.t('ice_cube.on', sentence: str) end - end - end - end diff --git a/lib/ice_cube/validations/day_of_week.rb b/lib/ice_cube/validations/day_of_week.rb index 991ee6fc..6416074e 100644 --- a/lib/ice_cube/validations/day_of_week.rb +++ b/lib/ice_cube/validations/day_of_week.rb @@ -1,7 +1,5 @@ module IceCube - module Validations::DayOfWeek - def day_of_week(dows) dows.each do |day, occs| occs.each do |occ| @@ -14,7 +12,6 @@ def day_of_week(dows) end class Validation - attr_reader :day, :occ def initialize(day, occ) @@ -30,15 +27,16 @@ def dst_adjust? true end - def validate(step_time, start_time) + def validate(step_time, _start_time) wday = step_time.wday - offset = (day < wday) ? (7 - wday + day) : (day - wday) + offset = day < wday ? (7 - wday + day) : (day - wday) wrapper = TimeUtil::TimeWrapper.new(step_time) wrapper.add :day, offset loop do which_occ, num_occ = TimeUtil.which_occurrence_in_month(wrapper.to_time, day) - this_occ = (occ < 0) ? (num_occ + occ + 1) : (occ) + this_occ = occ < 0 ? (num_occ + occ + 1) : occ break offset if which_occ == this_occ + wrapper.add :day, 7 offset += 7 end @@ -69,9 +67,6 @@ def build_ical(builder) sentence = segments.join(IceCube::I18n.t('ice_cube.array.two_words_connector')) IceCube::I18n.t('ice_cube.on', sentence: sentence) end - end - end - end diff --git a/lib/ice_cube/validations/day_of_year.rb b/lib/ice_cube/validations/day_of_year.rb index 6a9c1178..a5c8c5bb 100644 --- a/lib/ice_cube/validations/day_of_year.rb +++ b/lib/ice_cube/validations/day_of_year.rb @@ -1,12 +1,11 @@ module IceCube - module Validations::DayOfYear - def day_of_year(*days) days.flatten.each do |day| unless day.is_a?(Integer) raise ArgumentError, "expecting Integer value for day, got #{day.inspect}" end + validations_for(:day_of_year) << Validation.new(day) end clobber_base_validations(:month, :day, :wday) @@ -14,7 +13,6 @@ def day_of_year(*days) end class Validation - attr_reader :day def initialize(day) @@ -29,7 +27,7 @@ def dst_adjust? true end - def validate(step_time, start_time) + def validate(step_time, _start_time) days_in_year = TimeUtil.days_in_year(step_time) yday = day < 0 ? day + days_in_year + 1 : day offset = yday - step_time.yday @@ -49,13 +47,10 @@ def build_ical(builder) end StringBuilder.register_formatter(:day_of_year) do |entries| - str = StringBuilder.sentence(entries) + str = StringBuilder.sentence(entries) sentence = IceCube::I18n.t('ice_cube.days_of_year', count: entries.size, segments: str) IceCube::I18n.t('ice_cube.on', sentence: sentence) end - end - end - end diff --git a/lib/ice_cube/validations/fixed_value.rb b/lib/ice_cube/validations/fixed_value.rb index 2d9b1dad..19985c07 100644 --- a/lib/ice_cube/validations/fixed_value.rb +++ b/lib/ice_cube/validations/fixed_value.rb @@ -1,5 +1,4 @@ module IceCube - # This abstract validation class is used by the various "fixed-time" (e.g. # day, day_of_month, hour_of_day) Validation and ScheduleLock::Validation # modules. It is not a standalone rule validation module like the others. @@ -9,8 +8,7 @@ module IceCube # start_time # class Validations::FixedValue - - INTERVALS = {:min => 60, :sec => 60, :hour => 24, :month => 12, :wday => 7} + INTERVALS = { min: 60, sec: 60, hour: 24, month: 12, wday: 7 }.freeze def validate(time, start_time) case type @@ -89,7 +87,5 @@ def starting_unit(start_time) start = start % INTERVALS[type] if start < 0 start end - end - end diff --git a/lib/ice_cube/validations/hour_of_day.rb b/lib/ice_cube/validations/hour_of_day.rb index 291708e6..40281a01 100644 --- a/lib/ice_cube/validations/hour_of_day.rb +++ b/lib/ice_cube/validations/hour_of_day.rb @@ -1,7 +1,5 @@ module IceCube - module Validations::HourOfDay - # Add hour of day validations def hour_of_day(*hours) hours.flatten.each do |hour| @@ -19,6 +17,7 @@ def hour_of_day(*hours) def realign(opening_time, start_time) return super unless validations[:hour_of_day] + freq = base_interval_validation.interval first_hour = Array(validations[:hour_of_day]).min_by(&:value) @@ -34,9 +33,8 @@ def realign(opening_time, start_time) end class Validation < Validations::FixedValue - attr_reader :hour - alias :value :hour + alias value hour def initialize(hour) @hour = hour @@ -70,9 +68,6 @@ def build_ical(builder) str = StringBuilder.sentence(segments) IceCube::I18n.t('ice_cube.at_hours_of_the_day', count: segments.size, segments: str) end - end - end - end diff --git a/lib/ice_cube/validations/hourly_interval.rb b/lib/ice_cube/validations/hourly_interval.rb index edd73ed0..fc7a1a80 100644 --- a/lib/ice_cube/validations/hourly_interval.rb +++ b/lib/ice_cube/validations/hourly_interval.rb @@ -1,7 +1,5 @@ module IceCube - module Validations::HourlyInterval - def interval(interval) verify_alignment(interval, :hour, :interval) { |error| raise error } @@ -12,7 +10,6 @@ def interval(interval) end class Validation - attr_reader :interval def initialize(interval) @@ -37,7 +34,7 @@ def validate(step_time, start_time) end def build_s(builder) - builder.base = IceCube::I18n.t("ice_cube.each_hour", count: interval) + builder.base = IceCube::I18n.t('ice_cube.each_hour', count: interval) end def build_hash(builder) @@ -48,9 +45,6 @@ def build_ical(builder) builder['FREQ'] << 'HOURLY' builder['INTERVAL'] << interval unless interval == 1 end - end - end - end diff --git a/lib/ice_cube/validations/lock.rb b/lib/ice_cube/validations/lock.rb index 5e52dca0..06f02048 100644 --- a/lib/ice_cube/validations/lock.rb +++ b/lib/ice_cube/validations/lock.rb @@ -1,5 +1,4 @@ module IceCube - # This validation mixin is used by the various "fixed-time" (e.g. day, # day_of_month, hour_of_day) Validation and ScheduleLock::Validation modules. # It is not a standalone rule validation like the others. @@ -9,8 +8,7 @@ module IceCube # schedule's start_time # module Validations::Lock - - INTERVALS = {:min => 60, :sec => 60, :hour => 24, :month => 12, :wday => 7} + INTERVALS = { min: 60, sec: 60, hour: 24, month: 12, wday: 7 }.freeze def validate(time, start_time) case type @@ -89,7 +87,5 @@ def starting_unit(start_time) start += INTERVALS[type] while start < 0 start end - end - end diff --git a/lib/ice_cube/validations/minute_of_hour.rb b/lib/ice_cube/validations/minute_of_hour.rb index 03c2dd15..6eb99f83 100644 --- a/lib/ice_cube/validations/minute_of_hour.rb +++ b/lib/ice_cube/validations/minute_of_hour.rb @@ -1,7 +1,5 @@ module IceCube - module Validations::MinuteOfHour - def minute_of_hour(*minutes) minutes.flatten.each do |minute| unless minute.is_a?(Integer) @@ -26,9 +24,8 @@ def realign(opening_time, start_time) end class Validation < Validations::FixedValue - attr_reader :minute - alias :value :minute + alias value minute def initialize(minute) @minute = minute @@ -62,9 +59,6 @@ def build_ical(builder) str = StringBuilder.sentence(segments) IceCube::I18n.t('ice_cube.on_minutes_of_hour', count: segments.size, segments: str) end - end - end - end diff --git a/lib/ice_cube/validations/minutely_interval.rb b/lib/ice_cube/validations/minutely_interval.rb index 0599a6ca..917c8a3d 100644 --- a/lib/ice_cube/validations/minutely_interval.rb +++ b/lib/ice_cube/validations/minutely_interval.rb @@ -1,7 +1,5 @@ module IceCube - module Validations::MinutelyInterval - def interval(interval) verify_alignment(interval, :min, :interval) { |error| raise error } @@ -12,7 +10,6 @@ def interval(interval) end class Validation - attr_reader :interval def initialize(interval) @@ -48,9 +45,6 @@ def build_ical(builder) builder['FREQ'] << 'MINUTELY' builder['INTERVAL'] << interval unless interval == 1 end - end - end - end diff --git a/lib/ice_cube/validations/month_of_year.rb b/lib/ice_cube/validations/month_of_year.rb index e85bc2f9..cb25c290 100644 --- a/lib/ice_cube/validations/month_of_year.rb +++ b/lib/ice_cube/validations/month_of_year.rb @@ -1,12 +1,11 @@ module IceCube - module Validations::MonthOfYear - def month_of_year(*months) months.flatten.each do |month| unless month.is_a?(Integer) || month.is_a?(Symbol) raise ArgumentError, "expecting Integer or Symbol value for month, got #{month.inspect}" end + month = TimeUtil.sym_to_month(month) verify_alignment(month, :month, :month_of_year) { |error| raise error } validations_for(:month_of_year) << Validation.new(month) @@ -16,9 +15,8 @@ def month_of_year(*months) end class Validation < Validations::FixedValue - attr_reader :month - alias :value :month + alias value month def initialize(month) @month = month @@ -51,9 +49,6 @@ def build_ical(builder) StringBuilder.register_formatter(:month_of_year) do |segments| IceCube::I18n.t("ice_cube.in", target: StringBuilder.sentence(segments)) end - end - end - end diff --git a/lib/ice_cube/validations/monthly_interval.rb b/lib/ice_cube/validations/monthly_interval.rb index 49610a62..aff2b62f 100644 --- a/lib/ice_cube/validations/monthly_interval.rb +++ b/lib/ice_cube/validations/monthly_interval.rb @@ -1,7 +1,5 @@ module IceCube - module Validations::MonthlyInterval - def interval(interval) interval = normalized_interval(interval) verify_alignment(interval, :month, :interval) { |error| raise error } @@ -13,7 +11,6 @@ def interval(interval) end class Validation - attr_reader :interval def initialize(interval) @@ -48,9 +45,6 @@ def build_ical(builder) builder['FREQ'] << 'MONTHLY' builder['INTERVAL'] << interval unless interval == 1 end - end - end - end diff --git a/lib/ice_cube/validations/schedule_lock.rb b/lib/ice_cube/validations/schedule_lock.rb index 4dbbacda..195d39ad 100644 --- a/lib/ice_cube/validations/schedule_lock.rb +++ b/lib/ice_cube/validations/schedule_lock.rb @@ -1,7 +1,5 @@ module IceCube - module Validations::ScheduleLock - # Lock the given time units to the units from schedule's +start_time+ # These locks are all clobberable by other rules of the same #type # using +clobber_base_validation+ @@ -13,7 +11,6 @@ def schedule_lock(*types) end class Validation < Validations::FixedValue - attr_reader :type, :value def initialize(type) @@ -32,19 +29,13 @@ def dst_adjust? end # no -op - def build_s(builder) - end + def build_s(builder); end # no -op - def build_hash(builder) - end + def build_hash(builder); end # no -op - def build_ical(builder) - end - + def build_ical(builder); end end - end - end diff --git a/lib/ice_cube/validations/second_of_minute.rb b/lib/ice_cube/validations/second_of_minute.rb index f9208107..34d0ea49 100644 --- a/lib/ice_cube/validations/second_of_minute.rb +++ b/lib/ice_cube/validations/second_of_minute.rb @@ -1,7 +1,5 @@ module IceCube - module Validations::SecondOfMinute - def second_of_minute(*seconds) seconds.flatten.each do |second| unless second.is_a?(Integer) @@ -26,9 +24,8 @@ def realign(opening_time, start_time) end class Validation < Validations::FixedValue - attr_reader :second - alias :value :second + alias value second def initialize(second) @second = second @@ -62,9 +59,6 @@ def build_ical(builder) str = StringBuilder.sentence(segments) IceCube::I18n.t('ice_cube.on_seconds_of_minute', count: segments.size, segments: str) end - end - end - end diff --git a/lib/ice_cube/validations/secondly_interval.rb b/lib/ice_cube/validations/secondly_interval.rb index 92047edd..4bfdd527 100644 --- a/lib/ice_cube/validations/secondly_interval.rb +++ b/lib/ice_cube/validations/secondly_interval.rb @@ -1,7 +1,5 @@ module IceCube - module Validations::SecondlyInterval - def interval(interval) verify_alignment(interval, :sec, :interval) { |error| raise error } @@ -12,7 +10,6 @@ def interval(interval) end class Validation - attr_reader :interval def initialize(interval) @@ -45,9 +42,6 @@ def build_ical(builder) builder['FREQ'] << 'SECONDLY' builder['INTERVAL'] << interval unless interval == 1 end - end - end - end diff --git a/lib/ice_cube/validations/until.rb b/lib/ice_cube/validations/until.rb index 4172b7c2..b7303907 100644 --- a/lib/ice_cube/validations/until.rb +++ b/lib/ice_cube/validations/until.rb @@ -1,7 +1,5 @@ module IceCube - module Validations::Until - extend Deprecated # Value reader for limit @@ -16,7 +14,6 @@ def until(time) end class Validation - attr_reader :time def initialize(time) @@ -48,9 +45,6 @@ def build_hash(builder) def build_ical(builder) builder['UNTIL'] << IcalBuilder.ical_utc_format(time) end - end - end - end diff --git a/lib/ice_cube/validations/weekly_interval.rb b/lib/ice_cube/validations/weekly_interval.rb index c8444ea1..dfbc5b26 100644 --- a/lib/ice_cube/validations/weekly_interval.rb +++ b/lib/ice_cube/validations/weekly_interval.rb @@ -1,7 +1,5 @@ module IceCube - module Validations::WeeklyInterval - def interval(interval, week_start = :sunday) @interval = normalized_interval(interval) @week_start = TimeUtil.wday_to_sym(week_start) @@ -11,7 +9,6 @@ def interval(interval, week_start = :sunday) end class Validation - attr_reader :interval, :week_start def initialize(interval, week_start) @@ -29,6 +26,7 @@ def dst_adjust? def validate(step_time, start_time) return if step_time < start_time + t0, t1 = start_time, step_time d0 = Date.new(t0.year, t0.month, t0.day) d1 = Date.new(t1.year, t1.month, t1.day) @@ -49,14 +47,11 @@ def build_hash(builder) def build_ical(builder) builder['FREQ'] << 'WEEKLY' - unless interval == 1 - builder['INTERVAL'] << interval - builder['WKST'] << week_start.to_s.upcase[0..1] - end - end + return if interval == 1 + builder['INTERVAL'] << interval + builder['WKST'] << week_start.to_s.upcase[0..1] + end end - end - end diff --git a/lib/ice_cube/validations/yearly_interval.rb b/lib/ice_cube/validations/yearly_interval.rb index 7c2d3c90..44896df9 100644 --- a/lib/ice_cube/validations/yearly_interval.rb +++ b/lib/ice_cube/validations/yearly_interval.rb @@ -1,7 +1,5 @@ module IceCube - module Validations::YearlyInterval - def interval(interval) @interval = normalized_interval(interval) replace_validations_for(:interval, [Validation.new(@interval)]) @@ -10,7 +8,6 @@ def interval(interval) end class Validation - attr_reader :interval def initialize(interval) @@ -41,13 +38,10 @@ def build_hash(builder) def build_ical(builder) builder['FREQ'] << 'YEARLY' - unless interval == 1 - builder['INTERVAL'] << interval - end - end + return if interval == 1 + builder['INTERVAL'] << interval + end end - end - end diff --git a/lib/ice_cube/version.rb b/lib/ice_cube/version.rb index 3b75e422..aa34cb1f 100644 --- a/lib/ice_cube/version.rb +++ b/lib/ice_cube/version.rb @@ -1,5 +1,3 @@ module IceCube - - VERSION = '0.16.3' - + VERSION = '0.16.3'.freeze end