1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
module IceCube
class InputAlignment
def initialize(rule, value, rule_part)
@rule = rule
@value = value
@rule_part = rule_part
end
attr_reader :rule, :value, :rule_part
def verify(freq, options={}, &block)
@rule.validations[:interval] or return
case @rule
when DailyRule
verify_wday_alignment(freq, &block)
when MonthlyRule
verify_month_alignment(freq, &block)
else
verify_freq_alignment(freq, &block)
end
end
private
def interval_validation
@interval_validation ||= @rule.validations[:interval].first
end
def interval_value
@interval_value ||= (rule_part == :interval) ? value : interval_validation.interval
end
def fixed_validations
@fixed_validations ||= @rule.validations.values.flatten.select { |v|
interval_type = (v.type == :wday ? :day : v.type)
v.class < Validations::FixedValue &&
interval_type == rule.base_interval_validation.type
}
end
def verify_freq_alignment(freq)
interval_validation.type == freq or return
(last_validation = fixed_validations.min_by(&:value)) or return
alignment = (value - last_validation.value) % interval_validation.interval
return if alignment.zero?
validation_values = fixed_validations.map(&:value).join(', ')
if rule_part == :interval
message = "interval(#{value}) " \
"must be a multiple of " \
"intervals in #{last_validation.key}(#{validation_values})"
else
message = "intervals in #{last_validation.key}(#{validation_values}, #{value}) " \
"must be multiples of " \
"interval(#{interval_validation.interval})"
end
yield ArgumentError.new(message)
end
def verify_month_alignment(_freq)
return if interval_value == 1 || (interval_value % 12).zero?
return if fixed_validations.empty?
message = "month_of_year can only be used with interval(1) or multiples of interval(12)"
yield ArgumentError.new(message)
end
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?
message = "day can only be used with multiples of interval(7)"
else
(fixed_validation = fixed_validations.first) or return
message = "#{fixed_validation.key} can only be used with interval(1)"
end
yield ArgumentError.new(message)
end
end
end
|