Skip to content

Commit 7f7d5a7

Browse files
committed
Refactor: extract class for verifying input
Move methods related to input verification into their own object.
1 parent d698e84 commit 7f7d5a7

File tree

4 files changed

+94
-61
lines changed

4 files changed

+94
-61
lines changed

lib/ice_cube/input_alignment.rb

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

lib/ice_cube/rules/daily_rule.rb

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,6 @@ def initialize(interval = 1)
2020
reset
2121
end
2222

23-
def verify_alignment(value, freq, rule_part)
24-
return unless freq == :wday || freq == :day
25-
return unless @validations[:interval]
26-
27-
interval_validation = @validations[:interval].first
28-
interval_value = (rule_part == :interval) ? value : interval_validation.interval
29-
return if interval_value == 1
30-
31-
if freq == :wday
32-
return if (interval_value % 7).zero?
33-
return if Array(@validations[:day]).empty?
34-
message = "day can only be used with multiples of interval(7)"
35-
else
36-
(fixed_validation = other_fixed_value_validations.first) or return
37-
message = "#{fixed_validation.key} can only be used with interval(1)"
38-
end
39-
40-
yield ArgumentError.new(message)
41-
end
42-
4323
end
4424

4525
end

lib/ice_cube/rules/monthly_rule.rb

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,6 @@ def initialize(interval = 1)
2020
reset
2121
end
2222

23-
def verify_alignment(value, freq, rule_part)
24-
return unless freq == :month
25-
return unless @validations[:interval]
26-
27-
interval_validation = @validations[:interval].first
28-
interval_value = (rule_part == :interval) ? value : interval_validation.interval
29-
return if interval_value == 1 || (interval_value % 12).zero?
30-
return if other_fixed_value_validations.empty?
31-
32-
message = "month_of_year can only be used with interval(1) or multiples of interval(12)"
33-
yield ArgumentError.new(message)
34-
end
35-
3623
end
3724

3825
end

lib/ice_cube/validated_rule.rb

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
require 'ice_cube/input_alignment'
2+
13
module IceCube
24

35
class ValidatedRule < Rule
@@ -42,14 +44,6 @@ def other_interval_validations
4244
Array(@validations[base_interval_validation.type])
4345
end
4446

45-
def other_fixed_value_validations
46-
@validations.values.flatten.select { |v|
47-
interval_type = (v.type == :wday ? :day : v.type)
48-
v.class < Validations::FixedValue &&
49-
interval_type == base_interval_validation.type
50-
}
51-
end
52-
5347
# Compute the next time after (or including) the specified time in respect
5448
# to the given start time
5549
def next_time(time, start_time, closing_time)
@@ -184,27 +178,10 @@ def validation_names
184178
VALIDATION_ORDER & @validations.keys
185179
end
186180

187-
def verify_alignment(value, freq, rule_part, options={})
188-
@validations[:interval] or return
189-
interval_validation = @validations[:interval].first
190-
interval_validation.type == freq or return
191-
fixed_validations = other_fixed_value_validations
192-
(last_validation = fixed_validations.min_by(&:value)) or return
193-
194-
alignment = (value - last_validation.value) % interval_validation.interval
195-
return if alignment.zero?
196-
197-
validation_values = fixed_validations.map(&:value).join(', ')
198-
if rule_part == :interval
199-
message = "interval(#{value}) " \
200-
"must be a multiple of " \
201-
"intervals in #{last_validation.key}(#{validation_values})"
202-
else
203-
message = "intervals in #{last_validation.key}(#{validation_values}, #{value}) " \
204-
"must be multiples of " \
205-
"interval(#{interval_validation.interval})"
181+
def verify_alignment(value, freq, rule_part)
182+
InputAlignment.new(self, value, rule_part).verify(freq) do |error|
183+
yield error
206184
end
207-
yield ArgumentError.new(message)
208185
end
209186

210187
end

0 commit comments

Comments
 (0)