mirror of
https://github.com/hakanensari/frankfurter.git
synced 2024-11-21 18:42:29 +01:00
Ensure intuitive behavior when querying across holidays (#71)
This commit is contained in:
parent
e5815737c1
commit
7c99f214e6
File diff suppressed because one or more lines are too long
15
lib/day.rb
15
lib/day.rb
@ -3,13 +3,24 @@
|
||||
class Day < Sequel::Model
|
||||
dataset_module do
|
||||
def latest(date = Date.today)
|
||||
where(date: select(:date).where(Sequel.lit("date <= ?", date))
|
||||
where(date: select(:date).where(Sequel[:date] <= date)
|
||||
.order(Sequel.desc(:date))
|
||||
.limit(1))
|
||||
end
|
||||
|
||||
# Returns rates for a given date interval
|
||||
#
|
||||
# If the start date falls on a holiday/weekend, rates start from the closest preceding business day.
|
||||
def between(interval)
|
||||
where(date: interval)
|
||||
return where(false) if interval.begin > Date.today
|
||||
|
||||
previous_date = select(:date)
|
||||
.where(Sequel[:date] <= interval.begin)
|
||||
.order(Sequel.desc(:date))
|
||||
.limit(1)
|
||||
|
||||
where(Sequel.expr(:date) >= Sequel.function(:coalesce, previous_date, interval.begin))
|
||||
.where(Sequel.expr(:date) <= interval.end)
|
||||
end
|
||||
|
||||
def currencies
|
||||
|
@ -5,29 +5,54 @@ require "day"
|
||||
|
||||
describe Day do
|
||||
describe ".latest" do
|
||||
it "returns latest rates before given date" do
|
||||
it "returns latest available rates on given date" do
|
||||
date = Date.parse("2010-01-04")
|
||||
data = Day.latest(date)
|
||||
_(data.to_a.sample.date).must_equal(date)
|
||||
|
||||
date = Date.parse("2010-01-01")
|
||||
data = Day.latest(date)
|
||||
_(data.first.date).must_be(:<=, date)
|
||||
_(data.to_a.sample.date).must_equal(Date.parse("2009-12-31"))
|
||||
end
|
||||
|
||||
it "returns nothing if there are no rates before given date" do
|
||||
_(Day.latest(Date.parse("1998-01-01"))).must_be_empty
|
||||
it "returns nothing if date predates dataset" do
|
||||
_(Day.latest(Date.parse("1901-01-01"))).must_be_empty
|
||||
end
|
||||
end
|
||||
|
||||
describe ".between" do
|
||||
it "returns rates between given dates" do
|
||||
start_date = Date.parse("2010-01-01")
|
||||
end_date = Date.parse("2010-01-31")
|
||||
it "returns rates between given working dates" do
|
||||
start_date = Date.parse("2010-01-04")
|
||||
end_date = Date.parse("2010-01-29")
|
||||
dates = Day.between((start_date..end_date)).map(:date).sort
|
||||
_(dates.first).must_be(:>=, start_date)
|
||||
_(dates.last).must_be(:<=, end_date)
|
||||
_(dates.first).must_equal(start_date)
|
||||
_(dates.last).must_equal(end_date)
|
||||
end
|
||||
|
||||
it "returns nothing if there are no rates between given dates" do
|
||||
interval = (Date.parse("1998-01-01")..Date.parse("1998-01-31"))
|
||||
it "starts on preceding business day if start date is a holiday" do
|
||||
start_date = Date.parse("2024-11-03")
|
||||
end_date = Date.parse("2024-11-04")
|
||||
dates = Day.between((start_date..end_date)).map(:date)
|
||||
_(dates).must_include(Date.parse("2024-11-01"))
|
||||
end
|
||||
|
||||
it "returns nothing if end date predates dataset" do
|
||||
interval = (Date.parse("1901-01-01")..Date.parse("1901-01-31"))
|
||||
_(Day.between(interval)).must_be_empty
|
||||
end
|
||||
|
||||
it "allows start date to predate dataset" do
|
||||
start_date = Date.parse("1901-01-01")
|
||||
end_date = Date.parse("2024-01-01")
|
||||
dates = Day.between((start_date..end_date)).map(:date)
|
||||
_(dates).wont_be_empty
|
||||
end
|
||||
|
||||
it "returns nothing if queried for the future" do
|
||||
start_date = Date.today + 1
|
||||
end_date = start_date + 1
|
||||
dates = Day.between((start_date..end_date)).map(:date)
|
||||
_(dates).must_be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -22,8 +22,16 @@ module Quote
|
||||
end
|
||||
|
||||
it "quotes given date interval" do
|
||||
_(Date.parse(quote.formatted[:start_date])).must_be(:>=, dates.first)
|
||||
_(Date.parse(quote.formatted[:end_date])).must_be(:<=, dates.last)
|
||||
returned_start = Date.parse(quote.formatted[:start_date])
|
||||
returned_end = Date.parse(quote.formatted[:end_date])
|
||||
|
||||
# The returned start date should be the closest working day (before or on) the requested start
|
||||
_(returned_start).must_be(:<=, dates.first)
|
||||
# But it shouldn't be too far back (maybe 10 business days)
|
||||
_(returned_start).must_be(:>, dates.first - 10)
|
||||
|
||||
# End date should still be within the requested range
|
||||
_(returned_end).must_be(:<=, dates.last)
|
||||
end
|
||||
|
||||
it "quotes against the Euro" do
|
||||
|
Loading…
Reference in New Issue
Block a user