ice_cube 0.15.0 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/lib/ice_cube/deprecated.rb +4 -3
  3. data/lib/ice_cube/parsers/ical_parser.rb +1 -0
  4. data/lib/ice_cube/rule.rb +23 -9
  5. data/lib/ice_cube/rules/daily_rule.rb +1 -1
  6. data/lib/ice_cube/rules/hourly_rule.rb +1 -1
  7. data/lib/ice_cube/rules/minutely_rule.rb +1 -1
  8. data/lib/ice_cube/rules/monthly_rule.rb +1 -1
  9. data/lib/ice_cube/rules/secondly_rule.rb +1 -1
  10. data/lib/ice_cube/rules/weekly_rule.rb +27 -1
  11. data/lib/ice_cube/rules/yearly_rule.rb +1 -1
  12. data/lib/ice_cube/schedule.rb +7 -27
  13. data/lib/ice_cube/single_occurrence_rule.rb +1 -1
  14. data/lib/ice_cube/time_util.rb +3 -3
  15. data/lib/ice_cube/validated_rule.rb +16 -5
  16. data/lib/ice_cube/validations/count.rb +3 -3
  17. data/lib/ice_cube/validations/daily_interval.rb +2 -2
  18. data/lib/ice_cube/validations/day.rb +2 -2
  19. data/lib/ice_cube/validations/day_of_month.rb +2 -2
  20. data/lib/ice_cube/validations/day_of_week.rb +1 -1
  21. data/lib/ice_cube/validations/day_of_year.rb +4 -4
  22. data/lib/ice_cube/validations/fixed_value.rb +10 -10
  23. data/lib/ice_cube/validations/hour_of_day.rb +2 -2
  24. data/lib/ice_cube/validations/hourly_interval.rb +2 -2
  25. data/lib/ice_cube/validations/lock.rb +10 -10
  26. data/lib/ice_cube/validations/minute_of_hour.rb +2 -2
  27. data/lib/ice_cube/validations/minutely_interval.rb +2 -2
  28. data/lib/ice_cube/validations/month_of_year.rb +2 -2
  29. data/lib/ice_cube/validations/monthly_interval.rb +2 -2
  30. data/lib/ice_cube/validations/second_of_minute.rb +2 -2
  31. data/lib/ice_cube/validations/secondly_interval.rb +2 -2
  32. data/lib/ice_cube/validations/until.rb +2 -2
  33. data/lib/ice_cube/validations/weekly_interval.rb +3 -6
  34. data/lib/ice_cube/validations/yearly_interval.rb +2 -2
  35. data/lib/ice_cube/version.rb +1 -1
  36. data/spec/spec_helper.rb +15 -23
  37. metadata +6 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4da7e2dd818b7ab5f3c5dd023370bbc80f8e8ced
4
- data.tar.gz: e131a536a09b9c2bda6373b8c1f76cc2b8857245
3
+ metadata.gz: 01f55d89af28400fc30bdfe60ccacd66e42212b0
4
+ data.tar.gz: a7e85b8afe0d56f8b47c3e22139d080e035ee465
5
5
  SHA512:
6
- metadata.gz: 0ea3d24d220d7683a46c74b7b63bb2ab9959de7e1b4d08dd96664593f99bf78402e0f27fc395a4e21e46ce7cdea01a7780b7c5948fc10299a671cfe8f1c4a8f9
7
- data.tar.gz: ab2b07d2a5023c56a165b0cd3f8407f4c36816413efb005e1e31a8b82123cd4ba878a710b05832c2d521804d6dfb62fbd328199286b32e341e64f0e180fdd7ea
6
+ metadata.gz: a87067a8e0a099b1f9740bd4dab4ed408c72827c1498370b81ba3df3f6246fc7be12f8343f63832554dfa990f1754e5af365755831490d767df84b3462d49a41
7
+ data.tar.gz: d41ba1b2a5dc98db1522a38320452d9404a92510872a0473ba6dc9b440a5258352ea484ce28dc663908bf6bc19d747f4099035549865745377e4be9f035aed28
@@ -7,7 +7,7 @@ module IceCube
7
7
  def deprecated_alias(name, replacement)
8
8
  # Create a wrapped version
9
9
  define_method(name) do |*args, &block|
10
- warn "IceCube: #{self.class}##{name} is deprecated, please use ##{replacement} at: #{ caller[0] }"
10
+ warn "IceCube: #{self.class}##{name} is deprecated (use #{replacement})", caller[0]
11
11
  send replacement, *args, &block
12
12
  end
13
13
  end
@@ -21,14 +21,15 @@ module IceCube
21
21
  alias_method old_name, name
22
22
  # And replace it with a wrapped version
23
23
  define_method(name) do |*args, &block|
24
- warn "IceCube: #{self.class}##{name} is deprecated, please use ##{replacement} at: #{ caller[0] }"
24
+ warn "IceCube: #{self.class}##{name} is deprecated (use #{replacement})", caller[0]
25
25
  send old_name, *args, &block
26
26
  end
27
27
  end
28
28
 
29
29
  def self.schedule_options(schedule, options)
30
30
  if options[:start_date_override]
31
- warn "IceCube: :start_date_override option is deprecated, please use a block {|s| s.start_time = override }. at: #{ caller[0] }"
31
+ warn "IceCube: :start_date_override option is deprecated " \
32
+ "(use a block: `{|s| s.start_time = override }`)", caller[0]
32
33
  schedule.start_time = options[:start_date_override]
33
34
  end
34
35
  end
@@ -31,6 +31,7 @@ module IceCube
31
31
 
32
32
  ical.split(';').each do |rule|
33
33
  (name, value) = rule.split('=')
34
+ raise ArgumentError, "Invalid iCal rule component" if value.nil?
34
35
  value.strip!
35
36
  case name
36
37
  when 'FREQ'
@@ -11,6 +11,9 @@ module IceCube
11
11
 
12
12
  attr_reader :uses
13
13
 
14
+ def reset
15
+ end
16
+
14
17
  # Is this a terminating schedule?
15
18
  def terminating?
16
19
  until_time || occurrence_count
@@ -51,11 +54,6 @@ module IceCube
51
54
  raise MethodNotImplemented, "Expected to be overridden by subclasses"
52
55
  end
53
56
 
54
- # Reset the uses on the rule to 0
55
- def reset
56
- @uses = 0
57
- end
58
-
59
57
  def next_time(time, schedule, closing_time)
60
58
  end
61
59
 
@@ -73,18 +71,30 @@ module IceCube
73
71
  # Convert from a hash and create a rule
74
72
  def from_hash(original_hash)
75
73
  hash = IceCube::FlexibleHash.new original_hash
76
- return nil unless match = hash[:rule_type].match(/\:\:(.+?)Rule/)
74
+
75
+ unless hash[:rule_type] && match = hash[:rule_type].match(/\:\:(.+?)Rule/)
76
+ raise ArgumentError, 'Invalid rule type'
77
+ end
77
78
 
78
79
  interval_type = match[1].downcase.to_sym
79
- raise ArgumentError, "Invalid rule frequency type: #{match[1]}" unless INTERVAL_TYPES.include?(interval_type)
80
+
81
+ unless INTERVAL_TYPES.include?(interval_type)
82
+ raise ArgumentError, "Invalid rule frequency type: #{match[1]}"
83
+ end
80
84
 
81
85
  rule = IceCube::Rule.send(interval_type, hash[:interval] || 1)
82
- rule.interval(hash[:interval] || 1, TimeUtil.wday_to_sym(hash[:week_start] || 0)) if match[1] == "Weekly"
86
+
87
+ if match[1] == "Weekly"
88
+ rule.interval(hash[:interval] || 1, TimeUtil.wday_to_sym(hash[:week_start] || 0))
89
+ end
90
+
83
91
  rule.until(TimeUtil.deserialize_time(hash[:until])) if hash[:until]
84
92
  rule.count(hash[:count]) if hash[:count]
93
+
85
94
  hash[:validations] && hash[:validations].each do |name, args|
86
95
  apply_validation(rule, name, args)
87
96
  end
97
+
88
98
  rule
89
99
  end
90
100
 
@@ -92,7 +102,11 @@ module IceCube
92
102
 
93
103
  def apply_validation(rule, name, args)
94
104
  name = name.to_sym
95
- raise ArgumentError, "Invalid rule validation type: #{name}" unless ValidatedRule::VALIDATION_ORDER.include?(name)
105
+
106
+ unless ValidatedRule::VALIDATION_ORDER.include?(name)
107
+ raise ArgumentError, "Invalid rule validation type: #{name}"
108
+ end
109
+
96
110
  args.is_a?(Array) ? rule.send(name, *args) : rule.send(name, args)
97
111
  end
98
112
 
@@ -4,7 +4,7 @@ module IceCube
4
4
 
5
5
  include Validations::DailyInterval
6
6
 
7
- def initialize(interval = 1, week_start = :sunday)
7
+ def initialize(interval = 1)
8
8
  super
9
9
  interval(interval)
10
10
  schedule_lock(:hour, :min, :sec)
@@ -4,7 +4,7 @@ module IceCube
4
4
 
5
5
  include Validations::HourlyInterval
6
6
 
7
- def initialize(interval = 1, week_start = :sunday)
7
+ def initialize(interval = 1)
8
8
  super
9
9
  interval(interval)
10
10
  schedule_lock(:min, :sec)
@@ -4,7 +4,7 @@ module IceCube
4
4
 
5
5
  include Validations::MinutelyInterval
6
6
 
7
- def initialize(interval = 1, week_start = :sunday)
7
+ def initialize(interval = 1)
8
8
  super
9
9
  interval(interval)
10
10
  schedule_lock(:sec)
@@ -4,7 +4,7 @@ module IceCube
4
4
 
5
5
  include Validations::MonthlyInterval
6
6
 
7
- def initialize(interval = 1, week_start = :sunday)
7
+ def initialize(interval = 1)
8
8
  super
9
9
  interval(interval)
10
10
  schedule_lock(:day, :hour, :min, :sec)
@@ -4,7 +4,7 @@ module IceCube
4
4
 
5
5
  include Validations::SecondlyInterval
6
6
 
7
- def initialize(interval = 1, week_start = :sunday)
7
+ def initialize(interval = 1)
8
8
  super
9
9
  interval(interval)
10
10
  reset
@@ -4,13 +4,39 @@ module IceCube
4
4
 
5
5
  include Validations::WeeklyInterval
6
6
 
7
+ attr_reader :week_start
8
+
7
9
  def initialize(interval = 1, week_start = :sunday)
8
- super
10
+ super(interval)
9
11
  interval(interval, week_start)
10
12
  schedule_lock(:wday, :hour, :min, :sec)
11
13
  reset
12
14
  end
13
15
 
16
+ # Calculate the effective start time for when the given start time is later
17
+ # in the week than one of the weekday validations, such that times could be
18
+ # missed by a 7-day jump using the weekly interval, or when selecting from a
19
+ # date that is misaligned from the schedule interval.
20
+ #
21
+ def realign(step_time, start_time)
22
+ time = TimeUtil::TimeWrapper.new(start_time)
23
+ offset = wday_offset(step_time, start_time)
24
+ time.add(:day, offset) if offset
25
+ time.to_time
26
+ end
27
+
28
+ def wday_offset(step_time, start_time)
29
+ wday_validations = other_interval_validations.select { |v| v.type == :wday }
30
+ return if wday_validations.none?
31
+
32
+ days = (step_time - start_time).to_i / ONE_DAY
33
+ interval = base_interval_validation.validate(step_time, start_time).to_i
34
+ min_wday = TimeUtil.normalize_wday(wday_validations.min_by(&:day).day, week_start)
35
+ step_wday = TimeUtil.normalize_wday(step_time.wday, week_start)
36
+
37
+ days + interval - step_wday + min_wday
38
+ end
39
+
14
40
  end
15
41
 
16
42
  end
@@ -4,7 +4,7 @@ module IceCube
4
4
 
5
5
  include Validations::YearlyInterval
6
6
 
7
- def initialize(interval = 1, week_start = :sunday)
7
+ def initialize(interval = 1)
8
8
  super
9
9
  interval(interval)
10
10
  schedule_lock(:month, :day, :hour, :min, :sec)
@@ -46,7 +46,7 @@ module IceCube
46
46
 
47
47
  # Add a recurrence time to the schedule
48
48
  def add_recurrence_time(time)
49
- return nil if time.nil?
49
+ return if time.nil?
50
50
  rule = SingleOccurrenceRule.new(time)
51
51
  add_recurrence_rule rule
52
52
  time
@@ -57,7 +57,7 @@ module IceCube
57
57
 
58
58
  # Add an exception time to the schedule
59
59
  def add_exception_time(time)
60
- return nil if time.nil?
60
+ return if time.nil?
61
61
  rule = SingleOccurrenceRule.new(time)
62
62
  add_exception_rule rule
63
63
  time
@@ -68,6 +68,7 @@ module IceCube
68
68
 
69
69
  # Add a recurrence rule to the schedule
70
70
  def add_recurrence_rule(rule)
71
+ return if rule.nil?
71
72
  @all_recurrence_rules << rule unless @all_recurrence_rules.include?(rule)
72
73
  end
73
74
  alias :rrule :add_recurrence_rule
@@ -80,6 +81,7 @@ module IceCube
80
81
 
81
82
  # Add an exception rule to the schedule
82
83
  def add_exception_rule(rule)
84
+ return if rule.nil?
83
85
  @all_exception_rules << rule unless @all_exception_rules.include?(rule)
84
86
  end
85
87
  alias :exrule :add_exception_rule
@@ -413,7 +415,7 @@ module IceCube
413
415
  spans = options[:spans] == true && duration != 0
414
416
  Enumerator.new do |yielder|
415
417
  reset
416
- t1 = full_required? ? start_time : realign((spans ? opening_time - duration : opening_time))
418
+ t1 = full_required? ? start_time : opening_time - (spans ? duration : 0)
417
419
  loop do
418
420
  break unless (t0 = next_time(t1, closing_time))
419
421
  break if closing_time && t0 > closing_time
@@ -439,7 +441,7 @@ module IceCube
439
441
  loop do
440
442
  min_time = recurrence_rules_with_implicit_start_occurrence.reduce(nil) do |min_time, rule|
441
443
  begin
442
- new_time = rule.next_time(time, self, min_time || closing_time)
444
+ new_time = rule.next_time(time, start_time, min_time || closing_time)
443
445
  [min_time, new_time].compact.min
444
446
  rescue StopIteration
445
447
  min_time
@@ -462,7 +464,7 @@ module IceCube
462
464
  # is excluded from the schedule
463
465
  def exception_time?(time)
464
466
  @all_exception_rules.any? do |rule|
465
- rule.on?(time, self)
467
+ rule.on?(time, start_time)
466
468
  end
467
469
  end
468
470
 
@@ -502,28 +504,6 @@ module IceCube
502
504
  end
503
505
  end
504
506
 
505
- # If any rule has validations for values within the period, (overriding the
506
- # interval from start time, e.g. `day[_of_week]`), and the opening time is
507
- # offset from the interval multiplier such that it might miss the first
508
- # correct occurrence (e.g. repeat is every N weeks, but selecting from end
509
- # of week N-1, the first jump would go to end of week N and miss any
510
- # earlier validations in the week). This realigns the opening time to
511
- # the start of the interval's correct period (e.g. move to start of week N)
512
- # TODO: check if this is needed for validations other than `:wday`
513
- #
514
- def realign(opening_time)
515
- time = TimeUtil::TimeWrapper.new(opening_time)
516
- recurrence_rules.each do |rule|
517
- wday_validations = rule.other_interval_validations.select { |v| v.type == :wday } or next
518
- interval = rule.base_interval_validation.validate(opening_time, self).to_i
519
- offset = wday_validations
520
- .map { |v| v.validate(opening_time, self).to_i }
521
- .reduce(0) { |least, i| i > 0 && i <= interval && (i < least || least == 0) ? i : least }
522
- time.add(rule.base_interval_type, 7 - time.to_time.wday) if offset > 0
523
- end
524
- time.to_time
525
- end
526
-
527
507
  end
528
508
 
529
509
  end
@@ -13,7 +13,7 @@ module IceCube
13
13
  true
14
14
  end
15
15
 
16
- def next_time(t, schedule, closing_time)
16
+ def next_time(t, _, closing_time)
17
17
  unless closing_time && closing_time < t
18
18
  time if time.to_i >= t.to_i
19
19
  end
@@ -135,7 +135,7 @@ module IceCube
135
135
  def self.sym_to_month(sym)
136
136
  MONTHS.fetch(sym) do |k|
137
137
  MONTHS.values.detect { |i| i.to_s == k.to_s } or
138
- raise ArgumentError, "Expecting Fixnum or Symbol value for month. " \
138
+ raise ArgumentError, "Expecting Integer or Symbol value for month. " \
139
139
  "No such month: #{k.inspect}"
140
140
  end
141
141
  end
@@ -145,7 +145,7 @@ module IceCube
145
145
  def self.sym_to_wday(sym)
146
146
  DAYS.fetch(sym) do |k|
147
147
  DAYS.values.detect { |i| i.to_s == k.to_s } or
148
- raise ArgumentError, "Expecting Fixnum or Symbol value for weekday. " \
148
+ raise ArgumentError, "Expecting Integer or Symbol value for weekday. " \
149
149
  "No such weekday: #{k.inspect}"
150
150
  end
151
151
  end
@@ -155,7 +155,7 @@ module IceCube
155
155
  def self.wday_to_sym(wday)
156
156
  return sym = wday if DAYS.keys.include? wday
157
157
  DAYS.invert.fetch(wday) do |i|
158
- raise ArgumentError, "Expecting Fixnum value for weekday. " \
158
+ raise ArgumentError, "Expecting Integer value for weekday. " \
159
159
  "No such wday number: #{i.inspect}"
160
160
  end
161
161
  end
@@ -32,10 +32,17 @@ module IceCube
32
32
 
33
33
  attr_reader :validations
34
34
 
35
- def initialize(interval = 1, *)
35
+ def initialize(interval = 1)
36
36
  @validations = Hash.new
37
37
  end
38
38
 
39
+ # Reset the uses on the rule to 0
40
+ def reset
41
+ @time = nil
42
+ @start_time = nil
43
+ @uses = 0
44
+ end
45
+
39
46
  def base_interval_validation
40
47
  @validations[:interval].first
41
48
  end
@@ -49,10 +56,10 @@ module IceCube
49
56
  end
50
57
 
51
58
  # Compute the next time after (or including) the specified time in respect
52
- # to the given schedule
53
- def next_time(time, schedule, closing_time)
59
+ # to the given start time
60
+ def next_time(time, start_time, closing_time)
54
61
  @time = time
55
- @schedule = schedule
62
+ @start_time ||= realign(time, start_time)
56
63
 
57
64
  return nil unless find_acceptable_time_before(closing_time)
58
65
 
@@ -60,6 +67,10 @@ module IceCube
60
67
  @time
61
68
  end
62
69
 
70
+ def realign(opening_time, start_time)
71
+ start_time
72
+ end
73
+
63
74
  def skipped_for_dst
64
75
  @uses -= 1 if @uses > 0
65
76
  end
@@ -145,7 +156,7 @@ module IceCube
145
156
  #
146
157
  def validation_accepts_or_updates_time?(validations_for_type)
147
158
  res = validations_for_type.each_with_object([]) do |validation, offsets|
148
- r = validation.validate(@time, @schedule)
159
+ r = validation.validate(@time, @start_time)
149
160
  return true if r.nil? || r == 0
150
161
  offsets << r
151
162
  end
@@ -8,8 +8,8 @@ module IceCube
8
8
  end
9
9
 
10
10
  def count(max)
11
- unless max.nil? || max.is_a?(Fixnum)
12
- raise ArgumentError, "Expecting Fixnum or nil value for count, got #{max.inspect}"
11
+ unless max.nil? || max.is_a?(Integer)
12
+ raise ArgumentError, "Expecting Integer or nil value for count, got #{max.inspect}"
13
13
  end
14
14
  @count = max
15
15
  replace_validations_for(:count, max && [Validation.new(max, self)])
@@ -33,7 +33,7 @@ module IceCube
33
33
  false
34
34
  end
35
35
 
36
- def validate(time, schedule)
36
+ def validate(time, start_time)
37
37
  raise CountExceeded if rule.uses && rule.uses >= count
38
38
  end
39
39
 
@@ -26,8 +26,8 @@ module IceCube
26
26
  true
27
27
  end
28
28
 
29
- def validate(step_time, schedule)
30
- t0, t1 = schedule.start_time, step_time
29
+ def validate(step_time, start_time)
30
+ t0, t1 = start_time, step_time
31
31
  days = Date.new(t1.year, t1.month, t1.day) -
32
32
  Date.new(t0.year, t0.month, t0.day)
33
33
  offset = (days % interval).nonzero?
@@ -8,8 +8,8 @@ module IceCube
8
8
  days = days.flatten
9
9
  return self if days.empty?
10
10
  days.flatten.each do |day|
11
- unless day.is_a?(Fixnum) || day.is_a?(Symbol)
12
- raise ArgumentError, "expecting Fixnum or Symbol value for day, got #{day.inspect}"
11
+ unless day.is_a?(Integer) || day.is_a?(Symbol)
12
+ raise ArgumentError, "expecting Integer or Symbol value for day, got #{day.inspect}"
13
13
  end
14
14
  day = TimeUtil.sym_to_wday(day)
15
15
  validations_for(:day) << Validation.new(day)
@@ -4,8 +4,8 @@ module IceCube
4
4
 
5
5
  def day_of_month(*days)
6
6
  days.flatten.each do |day|
7
- unless day.is_a?(Fixnum)
8
- raise ArgumentError, "expecting Fixnum value for day, got #{day.inspect}"
7
+ unless day.is_a?(Integer)
8
+ raise ArgumentError, "expecting Integer value for day, got #{day.inspect}"
9
9
  end
10
10
  validations_for(:day_of_month) << Validation.new(day)
11
11
  end
@@ -30,7 +30,7 @@ module IceCube
30
30
  true
31
31
  end
32
32
 
33
- def validate(step_time, schedule)
33
+ def validate(step_time, start_time)
34
34
  wday = step_time.wday
35
35
  offset = (day < wday) ? (7 - wday + day) : (day - wday)
36
36
  wrapper = TimeUtil::TimeWrapper.new(step_time)
@@ -4,8 +4,8 @@ module IceCube
4
4
 
5
5
  def day_of_year(*days)
6
6
  days.flatten.each do |day|
7
- unless day.is_a?(Fixnum)
8
- raise ArgumentError, "expecting Fixnum value for day, got #{day.inspect}"
7
+ unless day.is_a?(Integer)
8
+ raise ArgumentError, "expecting Integer value for day, got #{day.inspect}"
9
9
  end
10
10
  validations_for(:day_of_year) << Validation.new(day)
11
11
  end
@@ -29,9 +29,9 @@ module IceCube
29
29
  true
30
30
  end
31
31
 
32
- def validate(step_time, schedule)
32
+ def validate(step_time, start_time)
33
33
  days_in_year = TimeUtil.days_in_year(step_time)
34
- yday = day < 0 ? day + days_in_year : day
34
+ yday = day < 0 ? day + days_in_year + 1 : day
35
35
  offset = yday - step_time.yday
36
36
  offset >= 0 ? offset : offset + days_in_year
37
37
  end
@@ -12,11 +12,11 @@ module IceCube
12
12
 
13
13
  INTERVALS = {:min => 60, :sec => 60, :hour => 24, :month => 12, :wday => 7}
14
14
 
15
- def validate(time, schedule)
15
+ def validate(time, start_time)
16
16
  case type
17
- when :day then validate_day_lock(time, schedule)
18
- when :hour then validate_hour_lock(time, schedule)
19
- else validate_interval_lock(time, schedule)
17
+ when :day then validate_day_lock(time, start_time)
18
+ when :hour then validate_hour_lock(time, start_time)
19
+ else validate_interval_lock(time, start_time)
20
20
  end
21
21
  end
22
22
 
@@ -25,8 +25,8 @@ module IceCube
25
25
  # Validate if the current time unit matches the same unit from the schedule
26
26
  # start time, returning the difference to the interval
27
27
  #
28
- def validate_interval_lock(time, schedule)
29
- t0 = starting_unit(schedule.start_time)
28
+ def validate_interval_lock(time, start_time)
29
+ t0 = starting_unit(start_time)
30
30
  t1 = time.send(type)
31
31
  t0 >= t1 ? t0 - t1 : INTERVALS[type] - t1 + t0
32
32
  end
@@ -34,8 +34,8 @@ module IceCube
34
34
  # Lock the hour if explicitly set by hour_of_day, but allow for the nearest
35
35
  # hour during DST start to keep the correct interval.
36
36
  #
37
- def validate_hour_lock(time, schedule)
38
- h0 = starting_unit(schedule.start_time)
37
+ def validate_hour_lock(time, start_time)
38
+ h0 = starting_unit(start_time)
39
39
  h1 = time.hour
40
40
  if h0 >= h1
41
41
  h0 - h1
@@ -57,7 +57,7 @@ module IceCube
57
57
  # Positive day values are taken literally so months with fewer days will
58
58
  # be skipped.
59
59
  #
60
- def validate_day_lock(time, schedule)
60
+ def validate_day_lock(time, start_time)
61
61
  days_in_month = TimeUtil.days_in_month(time)
62
62
  date = Date.new(time.year, time.month, time.day)
63
63
 
@@ -68,7 +68,7 @@ module IceCube
68
68
  start = value
69
69
  month_overflow = 0
70
70
  else
71
- start = TimeUtil.day_of_month(schedule.start_time.day, date)
71
+ start = TimeUtil.day_of_month(start_time.day, date)
72
72
  month_overflow = 0
73
73
  end
74
74
 
@@ -5,8 +5,8 @@ module IceCube
5
5
  # Add hour of day validations
6
6
  def hour_of_day(*hours)
7
7
  hours.flatten.each do |hour|
8
- unless hour.is_a?(Fixnum)
9
- raise ArgumentError, "expecting Fixnum value for hour, got #{hour.inspect}"
8
+ unless hour.is_a?(Integer)
9
+ raise ArgumentError, "expecting Integer value for hour, got #{hour.inspect}"
10
10
  end
11
11
  validations_for(:hour_of_day) << Validation.new(hour)
12
12
  end
@@ -25,8 +25,8 @@ module IceCube
25
25
  false
26
26
  end
27
27
 
28
- def validate(step_time, schedule)
29
- t0, t1 = schedule.start_time.to_i, step_time.to_i
28
+ def validate(step_time, start_time)
29
+ t0, t1 = start_time.to_i, step_time.to_i
30
30
  sec = (t1 - t1 % ONE_HOUR) -
31
31
  (t0 - t0 % ONE_HOUR)
32
32
  hours = sec / ONE_HOUR
@@ -12,11 +12,11 @@ module IceCube
12
12
 
13
13
  INTERVALS = {:min => 60, :sec => 60, :hour => 24, :month => 12, :wday => 7}
14
14
 
15
- def validate(time, schedule)
15
+ def validate(time, start_time)
16
16
  case type
17
- when :day then validate_day_lock(time, schedule)
18
- when :hour then validate_hour_lock(time, schedule)
19
- else validate_interval_lock(time, schedule)
17
+ when :day then validate_day_lock(time, start_time)
18
+ when :hour then validate_hour_lock(time, start_time)
19
+ else validate_interval_lock(time, start_time)
20
20
  end
21
21
  end
22
22
 
@@ -25,8 +25,8 @@ module IceCube
25
25
  # Validate if the current time unit matches the same unit from the schedule
26
26
  # start time, returning the difference to the interval
27
27
  #
28
- def validate_interval_lock(time, schedule)
29
- t0 = starting_unit(schedule.start_time)
28
+ def validate_interval_lock(time, start_time)
29
+ t0 = starting_unit(start_time)
30
30
  t1 = time.send(type)
31
31
  t0 >= t1 ? t0 - t1 : INTERVALS[type] - t1 + t0
32
32
  end
@@ -34,8 +34,8 @@ module IceCube
34
34
  # Lock the hour if explicitly set by hour_of_day, but allow for the nearest
35
35
  # hour during DST start to keep the correct interval.
36
36
  #
37
- def validate_hour_lock(time, schedule)
38
- h0 = starting_unit(schedule.start_time)
37
+ def validate_hour_lock(time, start_time)
38
+ h0 = starting_unit(start_time)
39
39
  h1 = time.hour
40
40
  if h0 >= h1
41
41
  h0 - h1
@@ -57,7 +57,7 @@ module IceCube
57
57
  # Positive day values are taken literally so months with fewer days will
58
58
  # be skipped.
59
59
  #
60
- def validate_day_lock(time, schedule)
60
+ def validate_day_lock(time, start_time)
61
61
  days_in_month = TimeUtil.days_in_month(time)
62
62
  date = Date.new(time.year, time.month, time.day)
63
63
 
@@ -68,7 +68,7 @@ module IceCube
68
68
  start = value
69
69
  month_overflow = 0
70
70
  else
71
- start = TimeUtil.day_of_month(schedule.start_time.day, date)
71
+ start = TimeUtil.day_of_month(start_time.day, date)
72
72
  month_overflow = 0
73
73
  end
74
74
 
@@ -4,8 +4,8 @@ module IceCube
4
4
 
5
5
  def minute_of_hour(*minutes)
6
6
  minutes.flatten.each do |minute|
7
- unless minute.is_a?(Fixnum)
8
- raise ArgumentError, "expecting Fixnum value for minute, got #{minute.inspect}"
7
+ unless minute.is_a?(Integer)
8
+ raise ArgumentError, "expecting Integer value for minute, got #{minute.inspect}"
9
9
  end
10
10
  validations_for(:minute_of_hour) << Validation.new(minute)
11
11
  end
@@ -25,8 +25,8 @@ module IceCube
25
25
  false
26
26
  end
27
27
 
28
- def validate(step_time, schedule)
29
- t0, t1 = schedule.start_time.to_i, step_time.to_i
28
+ def validate(step_time, start_time)
29
+ t0, t1 = start_time.to_i, step_time.to_i
30
30
  sec = (t1 - t1 % ONE_MINUTE) -
31
31
  (t0 - t0 % ONE_MINUTE)
32
32
  minutes = sec / ONE_MINUTE
@@ -4,8 +4,8 @@ module IceCube
4
4
 
5
5
  def month_of_year(*months)
6
6
  months.flatten.each do |month|
7
- unless month.is_a?(Fixnum) || month.is_a?(Symbol)
8
- raise ArgumentError, "expecting Fixnum or Symbol value for month, got #{month.inspect}"
7
+ unless month.is_a?(Integer) || month.is_a?(Symbol)
8
+ raise ArgumentError, "expecting Integer or Symbol value for month, got #{month.inspect}"
9
9
  end
10
10
  month = TimeUtil.sym_to_month(month)
11
11
  validations_for(:month_of_year) << Validation.new(month)
@@ -25,8 +25,8 @@ module IceCube
25
25
  true
26
26
  end
27
27
 
28
- def validate(step_time, schedule)
29
- t0, t1 = schedule.start_time, step_time
28
+ def validate(step_time, start_time)
29
+ t0, t1 = start_time, step_time
30
30
  months = (t1.month - t0.month) +
31
31
  (t1.year - t0.year) * 12
32
32
  offset = (months % interval).nonzero?
@@ -4,8 +4,8 @@ module IceCube
4
4
 
5
5
  def second_of_minute(*seconds)
6
6
  seconds.flatten.each do |second|
7
- unless second.is_a?(Fixnum)
8
- raise ArgumentError, "Expecting Fixnum value for second, got #{second.inspect}"
7
+ unless second.is_a?(Integer)
8
+ raise ArgumentError, "Expecting Integer value for second, got #{second.inspect}"
9
9
  end
10
10
  validations_for(:second_of_minute) << Validation.new(second)
11
11
  end
@@ -25,8 +25,8 @@ module IceCube
25
25
  false
26
26
  end
27
27
 
28
- def validate(step_time, schedule)
29
- seconds = step_time.to_i - schedule.start_time.to_i
28
+ def validate(step_time, start_time)
29
+ seconds = step_time.to_i - start_time.to_i
30
30
  offset = (seconds % interval).nonzero?
31
31
  interval - offset if offset
32
32
  end
@@ -32,8 +32,8 @@ module IceCube
32
32
  false
33
33
  end
34
34
 
35
- def validate(step_time, schedule)
36
- end_time = TimeUtil.ensure_time(time, schedule.start_time, true)
35
+ def validate(step_time, start_time)
36
+ end_time = TimeUtil.ensure_time(time, start_time, true)
37
37
  raise UntilExceeded if step_time > end_time
38
38
  end
39
39
 
@@ -12,10 +12,6 @@ module IceCube
12
12
  self
13
13
  end
14
14
 
15
- def week_start
16
- @week_start
17
- end
18
-
19
15
  class Validation
20
16
 
21
17
  attr_reader :interval, :week_start
@@ -33,8 +29,9 @@ module IceCube
33
29
  true
34
30
  end
35
31
 
36
- def validate(step_time, schedule)
37
- t0, t1 = schedule.start_time, step_time
32
+ def validate(step_time, start_time)
33
+ return if step_time < start_time
34
+ t0, t1 = start_time, step_time
38
35
  d0 = Date.new(t0.year, t0.month, t0.day)
39
36
  d1 = Date.new(t1.year, t1.month, t1.day)
40
37
  days = (d1 - TimeUtil.normalize_wday(d1.wday, week_start)) -
@@ -25,8 +25,8 @@ module IceCube
25
25
  true
26
26
  end
27
27
 
28
- def validate(step_time, schedule)
29
- years = step_time.year - schedule.start_time.year
28
+ def validate(step_time, start_time)
29
+ years = step_time.year - start_time.year
30
30
  offset = (years % interval).nonzero?
31
31
  interval - offset if offset
32
32
  end
@@ -1,5 +1,5 @@
1
1
  module IceCube
2
2
 
3
- VERSION = '0.15.0'
3
+ VERSION = '0.16.0'
4
4
 
5
5
  end
@@ -1,3 +1,6 @@
1
+ require "bundler/setup"
2
+ require 'ice_cube'
3
+
1
4
  begin
2
5
  require 'simplecov'
3
6
  SimpleCov.start
@@ -5,8 +8,6 @@ rescue LoadError
5
8
  # okay
6
9
  end
7
10
 
8
- require File.dirname(__FILE__) + '/../lib/ice_cube'
9
-
10
11
  IceCube.compatibility = 12
11
12
 
12
13
  DAY = Time.utc(2010, 3, 1)
@@ -19,46 +20,37 @@ WORLD_TIME_ZONES = [
19
20
  ]
20
21
 
21
22
  RSpec.configure do |config|
23
+ # Enable flags like --only-failures and --next-failure
24
+ config.example_status_persistence_file_path = ".rspec_status"
25
+
26
+ config.expect_with :rspec do |c|
27
+ c.syntax = :expect
28
+ end
29
+
22
30
  Dir[File.dirname(__FILE__) + '/support/**/*'].each { |f| require f }
23
31
 
24
32
  config.include WarningHelpers
25
33
 
26
- config.around :each, :if_active_support_time => true do |example|
27
- example.run if defined? ActiveSupport
28
- end
29
-
30
- config.around :each, :if_active_support_time => false do |example|
31
- unless defined? ActiveSupport
32
- stubbed_active_support = ::ActiveSupport = Module.new
33
- example.run
34
- Object.send :remove_const, :ActiveSupport
34
+ config.before :each do |example|
35
+ if example.metadata[:requires_active_support]
36
+ raise 'ActiveSupport required but not present' unless defined?(ActiveSupport)
35
37
  end
36
38
  end
37
39
 
38
40
  config.around :each do |example|
39
41
  if zone = example.metadata[:system_time_zone]
40
- @orig_zone = ENV['TZ']
42
+ orig_zone = ENV['TZ']
41
43
  ENV['TZ'] = zone
42
44
  example.run
43
- ENV['TZ'] = @orig_zone
45
+ ENV['TZ'] = orig_zone
44
46
  else
45
47
  example.run
46
48
  end
47
49
  end
48
50
 
49
- config.before :each do
50
- if time_args = @example.metadata[:system_time]
51
- case time_args
52
- when Array then Time.stub!(:now).and_return Time.local(*time_args)
53
- when Time then Time.stub!(:now).and_return time_args
54
- end
55
- end
56
- end
57
-
58
51
  config.around :each, expect_warnings: true do |example|
59
52
  capture_warnings do
60
53
  example.run
61
54
  end
62
55
  end
63
-
64
56
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ice_cube
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.0
4
+ version: 0.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Crepezzi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-28 00:00:00.000000000 Z
11
+ date: 2017-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">"
32
32
  - !ruby/object:Gem::Version
33
- version: 2.12.0
33
+ version: '3'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">"
39
39
  - !ruby/object:Gem::Version
40
- version: 2.12.0
40
+ version: '3'
41
41
  description: ice_cube is a recurring date library for Ruby. It allows for quick,
42
42
  programatic expansion of recurring date rules.
43
43
  email: john@crepezzi.com