diff --git a/lib/time_iterator.rb b/lib/time_iterator.rb index 1502e48..5cc3d8d 100644 --- a/lib/time_iterator.rb +++ b/lib/time_iterator.rb @@ -18,29 +18,17 @@ module TimeIterator }.freeze ITERATE_BY = (PERIODS.keys + PERIODS.values).freeze - private def valid_period?(period) - raise ArgumentError, "Unknown time period: #{period}" unless PERIODS.include?(period) - end - - private def method_for_period(method, period) - period = period.to_sym - valid_period?(period) - send("#{method}_#{period}") - end + class << self + def iterate(start, by:, every: 1) + by = by.to_sym - def iterate(by:, every: 1) - by = by.to_sym + raise ArgumentError, "Unknown period to iterate by: #{by}" unless ITERATE_BY.include?(by) - raise ArgumentError, "Unknown period to iterate by: #{by}" unless ITERATE_BY.include?(by) - - Enumerator.new do |block| - (0..INFINITY).each do |num| - block << (self + (num.send(by) * every)) + Enumerator.new do |block| + (0..INFINITY).each do |num| + block << (start + (num.send(by) * every)) + end end end end end - -class Time - include TimeIterator -end diff --git a/lib/time_iterator/core_ext/time.rb b/lib/time_iterator/core_ext/time.rb index ddedf73..0d61719 100644 --- a/lib/time_iterator/core_ext/time.rb +++ b/lib/time_iterator/core_ext/time.rb @@ -1,5 +1,15 @@ # Inject convenience methods into Time. class Time + private def valid_period?(period) + raise ArgumentError, "Unknown time period: #{period}" unless TimeIterator::PERIODS.include?(period) + end + + private def method_for_period(method, period) + period = period.to_sym + valid_period?(period) + send("#{method}_#{period}") + end + def beginning_of(period) method_for_period(:beginning_of, period) end diff --git a/spec/time_iterator/core_ext/time_spec.rb b/spec/time_iterator/core_ext/time_spec.rb index 41a08c2..5914234 100644 --- a/spec/time_iterator/core_ext/time_spec.rb +++ b/spec/time_iterator/core_ext/time_spec.rb @@ -1,14 +1,6 @@ RSpec.describe Time do let(:time) { described_class.now } - describe 'period check' do - it 'raises on invalid period' do - expect { time.beginning_of(:time) }.to raise_error(ArgumentError) - expect { time.end_of(:universe) }.to raise_error(ArgumentError) - expect { time.iterate(by: :colors) }.to raise_error(ArgumentError) - end - end - describe '#beginning_of' do periods2methods = { minute: :beginning_of_minute, @@ -25,6 +17,10 @@ expect(time.beginning_of(period)).to eq time.send(method) end end + + it 'raises on invalid period' do + expect { time.beginning_of(:time) }.to raise_error(ArgumentError) + end end describe '#end_of' do @@ -43,6 +39,10 @@ expect(time.end_of(period)).to eq time.send(method) end end + + it 'raises on invalid period' do + expect { time.end_of(:universe) }.to raise_error(ArgumentError) + end end describe '#days_in_month/year' do diff --git a/spec/time_iterator_spec.rb b/spec/time_iterator_spec.rb index fbe3be2..3b7d808 100644 --- a/spec/time_iterator_spec.rb +++ b/spec/time_iterator_spec.rb @@ -1,9 +1,15 @@ RSpec.describe TimeIterator do let(:time) { Time.now } - describe '#iterate' do + describe '.iterate' do it 'uses an Enumerator' do - expect( time.iterate(by: :day) ).to be_a(Enumerator) + expect( described_class.iterate(time, by: :day) ).to be_a(Enumerator) + end + + it 'raises on an invalid period' do + expect do + described_class.iterate(time, by: :colors) + end.to raise_error(ArgumentError) end [ @@ -12,20 +18,20 @@ ].each do |period| it "iterates by #{period}" do expect( - time.iterate(by: period).take(3) + described_class.iterate(time, by: period).take(3) ).to eq [time, time + 1.send(period), time + 2.send(period)] end end it 'iterates every X periods' do expect( - time.iterate(by: :day, every: 3).take(3) + described_class.iterate(time, by: :day, every: 3).take(3) ).to eq [time, time + 3.days, time + 6.days] end it 'does not alter the original time' do orig = time.clone - time.iterate(by: :day).take(5) + described_class.iterate(time, by: :day).take(5) expect( time ).to eq orig end end