Skip to content

Commit edd67ba

Browse files
committed
Add code coverage
1 parent 8d194c7 commit edd67ba

7 files changed

Lines changed: 104 additions & 9 deletions

File tree

lib/sof/cycles/end_of.rb

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def self.examples
2727
end
2828

2929
def to_s
30-
return dormant_to_s if dormant?
30+
return dormant_to_s if parser.dormant? || from_date.nil?
3131

3232
"#{volume}x by #{final_date.to_fs(:american)}"
3333
end
@@ -45,12 +45,18 @@ def last_completed(_ = nil) = from_date&.to_date
4545
# Cycle.for("V1E18MF2020-01-09")
4646
# .expiration_of(anchor: "2020-06-04".to_date)
4747
# # => #<Date: 2021-06-30>
48-
def expiration_of(_ = nil, anchor: nil) = final_date
48+
def expiration_of(_ = nil, anchor: nil)
49+
return nil if parser.dormant? || from_date.nil?
50+
final_date
51+
end
4952

5053
# Is the supplied anchor date prior to the final date?
5154
#
5255
# @return [Boolean] true if the cycle is satisfied, false otherwise
53-
def satisfied_by?(_ = nil, anchor: Date.current) = anchor <= final_date
56+
def satisfied_by?(_ = nil, anchor: Date.current)
57+
return false if parser.dormant? || from_date.nil?
58+
anchor <= final_date
59+
end
5460

5561
# Calculates the final date of the cycle
5662
#
@@ -61,11 +67,14 @@ def satisfied_by?(_ = nil, anchor: Date.current) = anchor <= final_date
6167
# @example
6268
# Cycle.for("V1E18MF2020-01-09").final_date
6369
# # => #<Date: 2021-06-30>
64-
def final_date(_ = nil) = time_span
65-
.end_date(start_date - 1.send(period))
66-
.end_of_month
70+
def final_date(_ = nil)
71+
return nil if parser.dormant? || from_date.nil?
72+
time_span
73+
.end_date(start_date - 1.send(period))
74+
.end_of_month
75+
end
6776

68-
def start_date(_ = nil) = from_date.to_date
77+
def start_date(_ = nil) = from_date&.to_date
6978

7079
private
7180

lib/sof/cycles/volume_only.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class << self
1212
def handles?(sym) = sym.nil? || sym.to_s == "volume_only"
1313

1414
def validate_period(period)
15-
raise InvalidPeriod, <<~ERR.squish unless period.nil?
15+
raise Cycle::InvalidPeriod, <<~ERR.squish unless period.nil?
1616
Invalid period value of '#{period}' provided. Valid periods are:
1717
#{valid_periods.join(", ")}
1818
ERR

spec/sof/cycles/dormant_spec.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,20 @@ module SOF
4949
end
5050
end
5151

52+
describe "#to_s" do
53+
context "with a dormant Within cycle" do
54+
it "returns the cycle string representation with (dormant) suffix" do
55+
expect(within_cycle.to_s).to eq "2x within 180 days (dormant)"
56+
end
57+
end
58+
59+
context "with a dormant EndOf cycle" do
60+
it "returns the cycle string representation with (dormant) suffix" do
61+
expect(end_of_cycle.to_s).to eq "2x by the last day of the 17th subsequent month (dormant)"
62+
end
63+
end
64+
end
65+
5266
describe "#kind & #kind?" do
5367
it "returns the correct kind" do
5468
expect(within_cycle.kind).to eq(:dormant)

spec/sof/cycles/end_of_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ module SOF
2929
"2x by #{@end_date.to_fs(:american)}"
3030

3131
context "when the cycle is dormant" do
32-
before { allow(cycle).to receive(:dormant?).and_return(true) }
32+
before { allow(cycle.parser).to receive(:dormant?).and_return(true) }
3333

3434
it_behaves_like "#to_s returns",
3535
"2x by the last day of the 17th subsequent month"

spec/sof/cycles/volume_only_spec.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,18 @@ module SOF
4949
end
5050
end
5151

52+
describe ".validate_period" do
53+
it "raises an error if a period is provided" do
54+
expect {
55+
described_class.validate_period("D")
56+
}.to raise_error(Cycle::InvalidPeriod, /Invalid period value of 'D' provided/)
57+
end
58+
59+
it "does not raise an error if period is nil" do
60+
expect { described_class.validate_period(nil) }.not_to raise_error
61+
end
62+
end
63+
5264
describe "#satisfied_by?(completed_dates, anchor:)" do
5365
context "when the completions--judged from the anchor--satisfy the cycle" do
5466
it "returns true" do

spec/sof/parser_spec.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,22 @@ module SOF
4949
end
5050
end
5151

52+
describe "#from_data" do
53+
context "when notation has no from date" do
54+
it "returns an empty hash" do
55+
parser = described_class.new("V1L180D")
56+
expect(parser.from_data).to eq({})
57+
end
58+
end
59+
60+
context "when notation has a from date" do
61+
it "returns a hash with the from date" do
62+
parser = described_class.new("V1W1MF2024-01-01")
63+
expect(parser.from_data).to eq({from: "F2024-01-01"})
64+
end
65+
end
66+
end
67+
5268
describe "#valid?" do
5369
it "returns true if the notation is recognized" do
5470
aggregate_failures do

spec/sof/time_span_spec.rb

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,49 @@ module SOF
5959
expect(span.end_date_of_period("2022-01-15".to_date)).to eq Date.parse("2022-03-31")
6060
end
6161
end
62+
63+
describe "#begin_date_of_period" do
64+
it "for a quarter period returns the beginning of the quarter" do
65+
span = described_class.for("1", "Q")
66+
expect(span.begin_date_of_period("2022-02-15".to_date)).to eq Date.parse("2022-01-01")
67+
end
68+
69+
it "for a week period returns the beginning of the week" do
70+
span = described_class.for("1", "W")
71+
# 2022-01-15 is a Saturday, beginning of week is Monday 2022-01-10
72+
expect(span.begin_date_of_period("2022-01-15".to_date)).to eq Date.parse("2022-01-10")
73+
end
74+
75+
it "for a day period returns the same date" do
76+
span = described_class.for("1", "D")
77+
expect(span.begin_date_of_period("2022-01-15".to_date)).to eq Date.parse("2022-01-15")
78+
end
79+
end
80+
81+
describe "#duration" do
82+
it "for quarters returns the duration in months" do
83+
span = described_class.for("2", "Q")
84+
expect(span.duration).to eq 6.months
85+
end
86+
end
87+
88+
describe "#final_date" do
89+
it "returns nil if there is no period" do
90+
span = described_class.for("", "")
91+
expect(span.final_date(Date.parse("2022-01-15"))).to be_nil
92+
end
93+
94+
it "returns the end date for a valid period" do
95+
span = described_class.for("3", "M")
96+
expect(span.final_date(Date.parse("2022-01-15"))).to eq Date.parse("2022-04-15")
97+
end
98+
end
99+
100+
describe "#to_h" do
101+
it "returns a hash with period and period_count" do
102+
span = described_class.for("3", "M")
103+
expect(span.to_h).to eq({period: :month, period_count: 3})
104+
end
105+
end
62106
end
63107
end

0 commit comments

Comments
 (0)