Skip to content

Commit 9a32aa1

Browse files
authored
Merge pull request #15 from schwern/issue/#14
Remove core extensions, add `until`.
2 parents 5cda4b4 + ec252ff commit 9a32aa1

File tree

7 files changed

+68
-209
lines changed

7 files changed

+68
-209
lines changed

.rubocop.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ Style/AccessModifierDeclarations:
4444
Style/AsciiComments:
4545
Enabled: false
4646

47+
Style/BlockDelimiters:
48+
EnforcedStyle: "braces_for_chaining"
49+
4750
Style/FrozenStringLiteralComment:
4851
Enabled: false
4952

lib/time_iterator.rb

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,31 @@
11
require "active_support"
2-
require "active_support/core_ext/integer/time"
3-
require_relative "time_iterator/core_ext/numeric"
4-
require_relative "time_iterator/core_ext/time"
2+
require "active_support/duration"
53

64
# Time iteration.
75
module TimeIterator
8-
INFINITY = 1.0 / 0.0
9-
PERIODS = {
10-
second: :seconds,
11-
minute: :minutes,
12-
hour: :hours,
13-
day: :days,
14-
week: :weeks,
15-
month: :months,
16-
quarter: :quarters,
17-
year: :years
18-
}.freeze
19-
ITERATE_BY = (PERIODS.keys + PERIODS.values).freeze
20-
216
class << self
22-
def iterate(start, by:, every: 1)
23-
by = by.to_sym
7+
def iterate(start, by:, to: nil)
8+
raise ArgumentError, "`by` must be an ActiveSupport::Duration" unless by.is_a?(ActiveSupport::Duration)
9+
10+
return to ? iterate_to(start, by: by, to: to) : iterate_endless(start, by: by)
11+
end
2412

25-
raise ArgumentError, "Unknown period to iterate by: #{by}" unless ITERATE_BY.include?(by)
13+
private def iterate_endless(start, by:)
14+
Enumerator.new do |block|
15+
time = start
16+
loop do
17+
block << time
18+
time += by
19+
end
20+
end
21+
end
2622

23+
private def iterate_to(start, by:, to:)
2724
Enumerator.new do |block|
28-
(0..INFINITY).each do |num|
29-
block << (start + (num.send(by) * every))
25+
time = start
26+
while time <= to
27+
block << time
28+
time += by
3029
end
3130
end
3231
end

lib/time_iterator/core_ext/numeric.rb

Lines changed: 0 additions & 7 deletions
This file was deleted.

lib/time_iterator/core_ext/time.rb

Lines changed: 0 additions & 48 deletions
This file was deleted.

spec/time_iterator/core_ext/numeric_spec.rb

Lines changed: 0 additions & 13 deletions
This file was deleted.

spec/time_iterator/core_ext/time_spec.rb

Lines changed: 0 additions & 102 deletions
This file was deleted.

spec/time_iterator_spec.rb

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,64 @@
11
RSpec.describe TimeIterator do
2-
let(:time) { Time.now }
2+
let(:time) { Time.gm(2000, 1, 1, 0, 0, 0) }
33

44
describe '.iterate' do
55
it 'uses an Enumerator' do
6-
expect( described_class.iterate(time, by: :day) ).to be_a(Enumerator)
6+
expect(
7+
described_class.iterate(time, by: ActiveSupport::Duration.days(1))
8+
).to be_a(Enumerator)
79
end
810

9-
it 'raises on an invalid period' do
10-
expect do
11+
it 'raises on an invalid `by`' do
12+
expect {
1113
described_class.iterate(time, by: :colors)
12-
end.to raise_error(ArgumentError)
14+
}.to raise_error(ArgumentError)
1315
end
1416

15-
[
16-
:second, :minute, :hour, :day, :week, :month, :quarter, :year,
17-
:seconds, :minutes, :hours, :days, :weeks, :months, :quarter, :years
18-
].each do |period|
19-
it "iterates by #{period}" do
20-
expect(
21-
described_class.iterate(time, by: period).take(3)
22-
).to eq [time, time + 1.send(period), time + 2.send(period)]
23-
end
17+
it "iterates" do
18+
expect(
19+
described_class.iterate(
20+
Time.gm(2000, 1, 1), by: ActiveSupport::Duration.days(3)
21+
).take(3)
22+
).to eq [
23+
Time.gm(2000, 1, 1),
24+
Time.gm(2000, 1, 4),
25+
Time.gm(2000, 1, 7)
26+
]
27+
end
28+
29+
it "stops before `to`" do
30+
expect(
31+
described_class.iterate(
32+
Time.gm(2000, 1, 1),
33+
by: ActiveSupport::Duration.days(3),
34+
to: Time.gm(2000, 1, 12)
35+
).to_a
36+
).to eq [
37+
Time.gm(2000, 1, 1),
38+
Time.gm(2000, 1, 4),
39+
Time.gm(2000, 1, 7),
40+
Time.gm(2000, 1, 10)
41+
]
2442
end
2543

26-
it 'iterates every X periods' do
44+
it "includes `to`" do
2745
expect(
28-
described_class.iterate(time, by: :day, every: 3).take(3)
29-
).to eq [time, time + 3.days, time + 6.days]
46+
described_class.iterate(
47+
Time.gm(2000, 1, 1),
48+
by: ActiveSupport::Duration.days(3),
49+
to: Time.gm(2000, 1, 10)
50+
).to_a
51+
).to eq [
52+
Time.gm(2000, 1, 1),
53+
Time.gm(2000, 1, 4),
54+
Time.gm(2000, 1, 7),
55+
Time.gm(2000, 1, 10)
56+
]
3057
end
3158

3259
it 'does not alter the original time' do
3360
orig = time.clone
34-
described_class.iterate(time, by: :day).take(5)
61+
described_class.iterate(time, by: ActiveSupport::Duration.weeks(2)).take(5)
3562
expect( time ).to eq orig
3663
end
3764
end

0 commit comments

Comments
 (0)