diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b1fb9b..92c26b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ## fugit 1.10.0 not yet released +* Implement iterator-returning `Fugit::Cron#next` and `#prev` + ## fugit 1.9.0 released 2023-10-24 diff --git a/lib/fugit/cron.rb b/lib/fugit/cron.rb index b30371c..063a922 100644 --- a/lib/fugit/cron.rb +++ b/lib/fugit/cron.rb @@ -318,6 +318,33 @@ def previous_time(from=::EtOrbi::EoTime.now) t.time.translate(from.zone) end + # Used by Fugit::Cron#next and Fugit::Cron#prev + # + class CronIterator include ::Enumerable + attr_reader :cron, :start, :current, :direction + def initialize(cron, direction, start) + @cron = cron + @start = start + @current = start.dup + @direction = direction + end + def each + loop do + yield(@current = @cron.send(@direction, @current)) + end + end + end + + def next(from=::EtOrbi::EoTime.now) + + CronIterator.new(self, :next_time, from) + end + + def prev(from=::EtOrbi::EoTime.now) + + CronIterator.new(self, :previous_time, from) + end + # Mostly used as a #next_time sanity check. # Avoid for "business" use, it's slow. # diff --git a/spec/cron_spec.rb b/spec/cron_spec.rb index 611d5d9..f6b10a1 100644 --- a/spec/cron_spec.rb +++ b/spec/cron_spec.rb @@ -1631,6 +1631,55 @@ class Fugit::Cron::TimeCursor end end end + + describe '#within' do + end + + describe '#next' do + + it 'returns an iterator' do + + c = Fugit.parse_cron('0 12 * * mon#2') + + in_zone 'UTC' do + + expect( + c.next + .take(5) + .map(&:to_s) + ).to eq([ + '2024-03-11 12:00:00 Z', + '2024-04-08 12:00:00 Z', + '2024-05-13 12:00:00 Z', + '2024-06-10 12:00:00 Z', + '2024-07-08 12:00:00 Z' + ]) + end + end + end + + describe '#prev' do + + it 'returns an iterator' do + + c = Fugit.parse_cron('0 12 * * mon#2') + + in_zone 'UTC' do + + expect( + c.prev + .take(5) + .map(&:to_s) + ).to eq([ + '2024-02-12 12:00:00 Z', + '2024-01-08 12:00:00 Z', + '2023-12-11 12:00:00 Z', + '2023-11-13 12:00:00 Z', + '2023-10-09 12:00:00 Z' + ]) + end + end + end end describe Fugit do