2024-06-11 23:47:07 +02:00
|
|
|
import datetime
|
|
|
|
|
from decimal import Decimal
|
|
|
|
|
|
|
|
|
|
from money.currency import Currency
|
|
|
|
|
from money.money import Money
|
|
|
|
|
|
2024-06-12 00:44:30 +02:00
|
|
|
from xexe.exchange_rates import (
|
|
|
|
|
ExchangeRate,
|
|
|
|
|
ExchangeRates,
|
|
|
|
|
add_equal_rates,
|
|
|
|
|
add_inverse_rates,
|
|
|
|
|
)
|
2024-06-11 23:47:07 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_exchange_rate_creation_works():
|
|
|
|
|
|
|
|
|
|
a_rate = ExchangeRate(
|
|
|
|
|
from_currency=Currency.USD,
|
|
|
|
|
to_currency=Currency.EUR,
|
|
|
|
|
rate=Decimal("1.2"),
|
|
|
|
|
rate_date=datetime.date.today(),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
assert a_rate.from_currency.value == "USD"
|
|
|
|
|
assert a_rate.to_currency.value == "EUR"
|
|
|
|
|
assert a_rate.rate.amount == Decimal("1.2")
|
|
|
|
|
assert a_rate.rate_date == datetime.date.today()
|
|
|
|
|
|
|
|
|
|
|
2024-06-27 16:44:30 +02:00
|
|
|
def test_exchange_rate_can_hold_8_decimal_positions():
|
|
|
|
|
a_rate = ExchangeRate(
|
|
|
|
|
from_currency=Currency.USD,
|
|
|
|
|
to_currency=Currency.EUR,
|
|
|
|
|
rate=Decimal("1.12345678"),
|
|
|
|
|
rate_date=datetime.date.today(),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
assert a_rate.from_currency.value == "USD"
|
|
|
|
|
assert a_rate.to_currency.value == "EUR"
|
|
|
|
|
assert a_rate.rate.amount == Decimal("1.12345678")
|
|
|
|
|
assert a_rate.rate_date == datetime.date.today()
|
|
|
|
|
|
|
|
|
|
|
2024-06-11 23:47:07 +02:00
|
|
|
def test_descriptor_builds_properly():
|
|
|
|
|
|
|
|
|
|
a_rate = ExchangeRate(
|
|
|
|
|
from_currency=Currency.USD,
|
|
|
|
|
to_currency=Currency.EUR,
|
|
|
|
|
rate=Decimal("1.2"),
|
|
|
|
|
rate_date=datetime.date(2020, 3, 10),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
assert a_rate.descriptor == "USDEUR2020-03-10"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_exchange_rates_builds_index_properly():
|
|
|
|
|
|
|
|
|
|
a_rate = ExchangeRate(
|
|
|
|
|
from_currency=Currency.USD,
|
|
|
|
|
to_currency=Currency.EUR,
|
|
|
|
|
rate=Decimal("1.2"),
|
|
|
|
|
rate_date=datetime.date(2020, 3, 10),
|
|
|
|
|
)
|
|
|
|
|
another_rate = ExchangeRate(
|
|
|
|
|
from_currency=Currency.GBP,
|
|
|
|
|
to_currency=Currency.JPY,
|
|
|
|
|
rate=Decimal("10"),
|
|
|
|
|
rate_date=datetime.date(2019, 10, 3),
|
|
|
|
|
)
|
|
|
|
|
a_third_rate = ExchangeRate(
|
|
|
|
|
from_currency=Currency.NZD,
|
|
|
|
|
to_currency=Currency.PLN,
|
|
|
|
|
rate=Decimal("1.2"),
|
|
|
|
|
rate_date=datetime.date(2025, 1, 10),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
rates = ExchangeRates({a_rate, another_rate, a_third_rate})
|
|
|
|
|
|
|
|
|
|
assert len(rates._rate_index) == 3
|
|
|
|
|
assert "USDEUR2020-03-10" in rates._rate_index
|
|
|
|
|
assert "GBPJPY2019-10-03" in rates._rate_index
|
|
|
|
|
assert "NZDPLN2025-01-10" in rates._rate_index
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_present_currencies_works_fine():
|
|
|
|
|
a_rate = ExchangeRate(
|
|
|
|
|
from_currency=Currency.USD,
|
|
|
|
|
to_currency=Currency.EUR,
|
|
|
|
|
rate=Decimal("1.2"),
|
|
|
|
|
rate_date=datetime.date(2020, 3, 10),
|
|
|
|
|
)
|
|
|
|
|
another_rate = ExchangeRate(
|
|
|
|
|
from_currency=Currency.GBP,
|
|
|
|
|
to_currency=Currency.JPY,
|
|
|
|
|
rate=Decimal("10"),
|
|
|
|
|
rate_date=datetime.date(2019, 10, 3),
|
|
|
|
|
)
|
|
|
|
|
a_third_rate = ExchangeRate(
|
|
|
|
|
from_currency=Currency.NZD,
|
|
|
|
|
to_currency=Currency.PLN,
|
|
|
|
|
rate=Decimal("1.2"),
|
|
|
|
|
rate_date=datetime.date(2025, 1, 10),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
rates = ExchangeRates({a_rate, another_rate, a_third_rate})
|
|
|
|
|
|
|
|
|
|
assert rates.present_currencies == {
|
|
|
|
|
Currency.USD,
|
|
|
|
|
Currency.EUR,
|
|
|
|
|
Currency.JPY,
|
|
|
|
|
Currency.GBP,
|
|
|
|
|
Currency.NZD,
|
|
|
|
|
Currency.PLN,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_present_dates_works_fine():
|
|
|
|
|
a_rate = ExchangeRate(
|
|
|
|
|
from_currency=Currency.USD,
|
|
|
|
|
to_currency=Currency.EUR,
|
|
|
|
|
rate=Decimal("1.2"),
|
|
|
|
|
rate_date=datetime.date(2020, 3, 10),
|
|
|
|
|
)
|
|
|
|
|
another_rate = ExchangeRate(
|
|
|
|
|
from_currency=Currency.GBP,
|
|
|
|
|
to_currency=Currency.JPY,
|
|
|
|
|
rate=Decimal("10"),
|
|
|
|
|
rate_date=datetime.date(2019, 10, 3),
|
|
|
|
|
)
|
|
|
|
|
a_third_rate = ExchangeRate(
|
|
|
|
|
from_currency=Currency.NZD,
|
|
|
|
|
to_currency=Currency.PLN,
|
|
|
|
|
rate=Decimal("1.2"),
|
|
|
|
|
rate_date=datetime.date(2025, 1, 10),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
rates = ExchangeRates({a_rate, another_rate, a_third_rate})
|
|
|
|
|
|
|
|
|
|
assert rates.present_dates == {
|
|
|
|
|
datetime.date(2025, 1, 10),
|
|
|
|
|
datetime.date(2019, 10, 3),
|
|
|
|
|
datetime.date(2020, 3, 10),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2024-06-12 00:44:30 +02:00
|
|
|
def test_exchange_rates_is_rate_present_method_works_fine():
|
|
|
|
|
a_rate = ExchangeRate(
|
|
|
|
|
from_currency=Currency.USD,
|
|
|
|
|
to_currency=Currency.EUR,
|
|
|
|
|
rate=Decimal("1.2"),
|
|
|
|
|
rate_date=datetime.date(2020, 3, 10),
|
|
|
|
|
)
|
|
|
|
|
another_rate = ExchangeRate(
|
|
|
|
|
from_currency=Currency.GBP,
|
|
|
|
|
to_currency=Currency.JPY,
|
|
|
|
|
rate=Decimal("10"),
|
|
|
|
|
rate_date=datetime.date(2019, 10, 3),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
rates = ExchangeRates({a_rate})
|
|
|
|
|
|
|
|
|
|
assert rates.is_rate_present(a_rate)
|
|
|
|
|
assert not rates.is_rate_present(another_rate)
|
|
|
|
|
|
|
|
|
|
|
2024-06-11 23:47:07 +02:00
|
|
|
def test_add_equal_rates_returns_expected_values():
|
|
|
|
|
a_rate = ExchangeRate(
|
|
|
|
|
from_currency=Currency.USD,
|
|
|
|
|
to_currency=Currency.EUR,
|
|
|
|
|
rate=Decimal("1.2"),
|
|
|
|
|
rate_date=datetime.date(2020, 3, 10),
|
|
|
|
|
)
|
|
|
|
|
another_rate = ExchangeRate(
|
|
|
|
|
from_currency=Currency.GBP,
|
|
|
|
|
to_currency=Currency.JPY,
|
|
|
|
|
rate=Decimal("10"),
|
|
|
|
|
rate_date=datetime.date(2019, 10, 3),
|
|
|
|
|
)
|
|
|
|
|
a_third_rate = ExchangeRate(
|
|
|
|
|
from_currency=Currency.NZD,
|
|
|
|
|
to_currency=Currency.PLN,
|
|
|
|
|
rate=Decimal("1.2"),
|
|
|
|
|
rate_date=datetime.date(2025, 1, 10),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
rates = ExchangeRates({a_rate, another_rate, a_third_rate})
|
|
|
|
|
|
|
|
|
|
assert len(rates) == 3
|
|
|
|
|
|
|
|
|
|
rates = add_equal_rates(rates)
|
|
|
|
|
|
|
|
|
|
equal_rate_entry_count = len(list(rates.present_currencies)) * len(
|
|
|
|
|
rates.present_dates
|
|
|
|
|
)
|
|
|
|
|
assert len(rates) == equal_rate_entry_count + 3
|
|
|
|
|
assert (
|
|
|
|
|
len([rate for rate in rates if rate.from_currency == rate.to_currency])
|
|
|
|
|
== equal_rate_entry_count
|
|
|
|
|
)
|
|
|
|
|
for rate in rates:
|
|
|
|
|
if rate.from_currency == rate.to_currency:
|
|
|
|
|
assert rate.amount == Decimal(1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_add_equal_rates_runs_on_empty_rates():
|
|
|
|
|
|
|
|
|
|
empty_rates = ExchangeRates()
|
|
|
|
|
|
|
|
|
|
empty_rates = add_equal_rates(empty_rates)
|
|
|
|
|
|
|
|
|
|
assert True
|
2024-06-12 00:44:30 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_add_equal_rates_overwrites():
|
|
|
|
|
a_rate = ExchangeRate(
|
|
|
|
|
from_currency=Currency.USD,
|
|
|
|
|
to_currency=Currency.USD,
|
|
|
|
|
rate=Decimal("1.2"),
|
|
|
|
|
rate_date=datetime.date(2020, 3, 10),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
rates = ExchangeRates([a_rate])
|
|
|
|
|
|
|
|
|
|
assert len(rates) == 1
|
|
|
|
|
|
|
|
|
|
rates = add_equal_rates(rates, overwrite=True)
|
|
|
|
|
|
|
|
|
|
assert len(rates) == 1
|
|
|
|
|
assert list(rates)[0].amount == 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_add_equal_rates_does_not_overwrite():
|
|
|
|
|
a_rate = ExchangeRate(
|
|
|
|
|
from_currency=Currency.USD,
|
|
|
|
|
to_currency=Currency.USD,
|
|
|
|
|
rate=Decimal("1.2"),
|
|
|
|
|
rate_date=datetime.date(2020, 3, 10),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
rates = ExchangeRates([a_rate])
|
|
|
|
|
|
|
|
|
|
assert len(rates) == 1
|
|
|
|
|
|
|
|
|
|
rates = add_equal_rates(rates, overwrite=False)
|
|
|
|
|
|
|
|
|
|
assert len(rates) == 1
|
|
|
|
|
assert list(rates)[0].amount == Decimal("1.2")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_add_inverse_rates_returns_expected():
|
|
|
|
|
a_rate = ExchangeRate(
|
|
|
|
|
from_currency=Currency.EUR,
|
|
|
|
|
to_currency=Currency.USD,
|
2024-06-27 16:46:17 +02:00
|
|
|
rate=Decimal("1.12345000"),
|
2024-06-12 00:44:30 +02:00
|
|
|
rate_date=datetime.date(2020, 3, 10),
|
|
|
|
|
)
|
|
|
|
|
inverse_rate = ExchangeRate(
|
|
|
|
|
from_currency=Currency.USD,
|
|
|
|
|
to_currency=Currency.EUR,
|
2024-06-27 16:46:17 +02:00
|
|
|
rate=Decimal("0.89011527"),
|
2024-06-12 00:44:30 +02:00
|
|
|
rate_date=datetime.date(2020, 3, 10),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
rates = ExchangeRates([a_rate])
|
|
|
|
|
|
|
|
|
|
assert len(rates) == 1
|
|
|
|
|
|
|
|
|
|
rates = add_inverse_rates(rates)
|
|
|
|
|
|
|
|
|
|
assert len(rates) == 2
|
|
|
|
|
|
|
|
|
|
assert rates.is_rate_present(inverse_rate)
|
2024-06-27 16:46:17 +02:00
|
|
|
assert rates[inverse_rate.descriptor].amount == Decimal("0.89011527")
|
2024-06-12 00:44:30 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_add_inverse_rates_runs_on_empty_rates():
|
|
|
|
|
empty_rates = ExchangeRates()
|
|
|
|
|
|
|
|
|
|
empty_rates = add_inverse_rates(empty_rates)
|
|
|
|
|
|
|
|
|
|
assert True
|