Last active
September 11, 2020 07:12
-
-
Save rafaltrojanowski/a946f4a5aa7a493d1d9a49771a6c6f0a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'date' | |
def daily_cost(start_date, end_date, time_period_costs) | |
daily_cost = {} | |
if start_date > end_date | |
raise "Wrong time period given." | |
end | |
(start_date..end_date).each do |date| | |
time_period_costs.each do |time_period_cost| | |
unless time_period_cost[:cost].is_a?(Float) | |
raise "Wrong cost given." | |
end | |
daily_cost[date] ||= 0 | |
if time_period_cost[:time_period] == :daily | |
daily_cost[date] = time_period_cost[:cost] | |
elsif time_period_cost[:time_period] == :weekly | |
daily_cost[date] += time_period_cost[:cost] / 7 | |
elsif time_period_cost[:time_period] == :monthly | |
daily_cost[date] += time_period_cost[:cost] / days_in_month(date.year, date.month) | |
else | |
raise "Wrong time interval given." | |
end | |
end | |
end | |
daily_cost | |
end | |
def days_in_month(year, month) | |
Date.new(year, month, -1).day | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'spec_helper' | |
require_relative '../daily_cost.rb' | |
describe '#daily_cost' do | |
it 'should work when empty time periods passed in' do | |
expect(daily_cost(Date.new, Date.new, {})).to eq({}) | |
end | |
describe "error handling" do | |
it 'raises wrong time period' do | |
start_date = Date.new(2020, 9, 2) | |
end_date = Date.new(2020, 9, 1) | |
expect {daily_cost(start_date, end_date, {})} | |
.to raise_error(RuntimeError, "Wrong time period given.") | |
end | |
it 'raises wrong time interval' do | |
start_date = Date.new(2020, 9, 1) | |
end_date = Date.new(2020, 9, 2) | |
time_period_costs = [ | |
{ | |
time_period: :yearly, | |
cost: 30.0 | |
} | |
] | |
expect {daily_cost(start_date, end_date, time_period_costs)} | |
.to raise_error(RuntimeError, "Wrong time interval given.") | |
end | |
end | |
context 'when mixed time periods passed in' do | |
it 'returns correct value for all time periods' do | |
start_date = Date.new(2019, 10, 1) | |
end_date = Date.new(2019, 10, 3) | |
time_period_costs = [ | |
{ | |
time_period: :daily, | |
cost: 10.0 | |
}, | |
{ | |
time_period: :weekly, | |
cost: 70.0 | |
}, | |
{ | |
time_period: :monthly, | |
cost: 31.0 | |
} | |
] | |
expect(daily_cost(start_date, end_date, time_period_costs)) | |
.to eq({ | |
Date.new(2019, 10, 1) => 21.0, | |
Date.new(2019, 10, 2) => 21.0, | |
Date.new(2019, 10, 3) => 21.0 | |
}) | |
end | |
it 'returns correct value for daily and weekly' do | |
start_date = Date.new(2019, 10, 1) | |
end_date = Date.new(2019, 10, 3) | |
time_period_costs = [ | |
{ | |
time_period: :daily, | |
cost: 10.0 | |
}, | |
{ | |
time_period: :weekly, | |
cost: 70.0 | |
} | |
] | |
expect(daily_cost(start_date, end_date, time_period_costs)) | |
.to eq({ | |
Date.new(2019, 10, 1) => 20.0, | |
Date.new(2019, 10, 2) => 20.0, | |
Date.new(2019, 10, 3) => 20.0 | |
}) | |
end | |
end | |
context 'when single time period passed in' do | |
it 'works with daily time period' do | |
start_date = Date.new(2019, 10, 1) | |
end_date = Date.new(2019, 10, 3) | |
time_period_costs = [ | |
{ | |
time_period: :daily, | |
cost: 10.0 | |
} | |
] | |
expect(daily_cost(start_date, end_date, time_period_costs)) | |
.to eq({ | |
Date.new(2019, 10, 1) => 10.0, | |
Date.new(2019, 10, 2) => 10.0, | |
Date.new(2019, 10, 3) => 10.0 | |
}) | |
end | |
it 'works with weekly time period' do | |
start_date = Date.new(2019, 10, 1) | |
end_date = Date.new(2019, 10, 3) | |
time_period_costs = [ | |
{ | |
time_period: :weekly, | |
cost: 70.0 | |
} | |
] | |
expect(daily_cost(start_date, end_date, time_period_costs)) | |
.to eq({ | |
Date.new(2019, 10, 1) => 10.0, | |
Date.new(2019, 10, 2) => 10.0, | |
Date.new(2019, 10, 3) => 10.0 | |
}) | |
end | |
it 'works with monthly time period' do | |
start_date = Date.new(2019, 10, 1) | |
end_date = Date.new(2019, 10, 3) | |
time_period_costs = [ | |
{ | |
time_period: :monthly, | |
cost: 31.0 | |
} | |
] | |
expect(daily_cost(start_date, end_date, time_period_costs)) | |
.to eq({ | |
Date.new(2019, 10, 1) => 1.0, | |
Date.new(2019, 10, 2) => 1.0, | |
Date.new(2019, 10, 3) => 1.0 | |
}) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment