83 lines
2.5 KiB
Ruby
83 lines
2.5 KiB
Ruby
|
|
# frozen_string_literal: true
|
||
|
|
|
||
|
|
require_relative "helper"
|
||
|
|
require "peg_anchor"
|
||
|
|
require "peg"
|
||
|
|
|
||
|
|
describe PegAnchor do
|
||
|
|
let(:date) { Date.parse("2024-01-15") }
|
||
|
|
|
||
|
|
describe "matched-base peg substitution" do
|
||
|
|
it "uses the peg rate when request base matches the peg's base" do
|
||
|
|
blended = [
|
||
|
|
{ date:, base: "USD", quote: "AED", rate: 3.67, providers: [{ key: "ECB", rate: 0.0 }] },
|
||
|
|
]
|
||
|
|
|
||
|
|
result = PegAnchor.apply(blended, base: "USD")
|
||
|
|
aed = result.find { |r| r[:quote] == "AED" }
|
||
|
|
|
||
|
|
_(aed[:rate]).must_equal(3.6725)
|
||
|
|
end
|
||
|
|
|
||
|
|
it "preserves providers on peg-substituted rows, marking all excluded" do
|
||
|
|
blended = [
|
||
|
|
{ date:, base: "USD", quote: "AED", rate: 3.67, providers: [{ key: "ECB", rate: 3.67 }] },
|
||
|
|
]
|
||
|
|
|
||
|
|
result = PegAnchor.apply(blended, base: "USD")
|
||
|
|
aed = result.find { |r| r[:quote] == "AED" }
|
||
|
|
|
||
|
|
_(aed[:providers]).must_equal([{ key: "ECB", rate: 3.67, excluded: true }])
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
describe "cross-base peg substitution" do
|
||
|
|
it "anchors cross-base pegged quote through the peg's base" do
|
||
|
|
blended = [
|
||
|
|
{ date:, base: "EUR", quote: "USD", rate: 1.10, providers: [{ key: "ECB", rate: 0.0 }] },
|
||
|
|
{ date:, base: "EUR", quote: "AED", rate: 4.04, providers: [{ key: "ECB", rate: 0.0 }] },
|
||
|
|
]
|
||
|
|
|
||
|
|
result = PegAnchor.apply(blended, base: "EUR")
|
||
|
|
aed = result.find { |r| r[:quote] == "AED" }
|
||
|
|
|
||
|
|
_(aed[:rate]).must_be_close_to(1.10 * 3.6725, 0.0001)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
describe "synthesis of peg-only currencies" do
|
||
|
|
it "synthesizes rows for currencies providers do not cover" do
|
||
|
|
blended = [
|
||
|
|
{ date:, base: "EUR", quote: "GBP", rate: 0.86, providers: [{ key: "ECB", rate: 0.86 }] },
|
||
|
|
]
|
||
|
|
|
||
|
|
result = PegAnchor.apply(blended, base: "EUR")
|
||
|
|
fkp = result.find { |r| r[:quote] == "FKP" }
|
||
|
|
|
||
|
|
_(fkp).wont_be_nil
|
||
|
|
_(fkp[:rate]).must_be_close_to(0.86, 0.0001)
|
||
|
|
_(fkp.key?(:providers)).must_equal(false)
|
||
|
|
end
|
||
|
|
|
||
|
|
it "skips synthesized rows before peg start date" do
|
||
|
|
old_date = Date.parse("1900-01-01")
|
||
|
|
blended = [
|
||
|
|
{ date: old_date, base: "EUR", quote: "GBP", rate: 0.86, providers: [{ key: "ECB", rate: 0.0 }] },
|
||
|
|
]
|
||
|
|
|
||
|
|
result = PegAnchor.apply(blended, base: "EUR")
|
||
|
|
fkp = result.find { |r| r[:quote] == "FKP" }
|
||
|
|
|
||
|
|
_(fkp).must_be_nil
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
describe "empty input" do
|
||
|
|
it "returns an empty array when no rates are provided" do
|
||
|
|
result = PegAnchor.apply([], base: "EUR")
|
||
|
|
|
||
|
|
_(result).must_equal([])
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|