ice_cube 0.15.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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