Test outputs.

This commit is contained in:
Chris Berkhout 2021-08-04 15:34:52 +02:00
parent 5d0c6aaf03
commit 78b622eade
6 changed files with 288 additions and 1 deletions

View file

@ -58,6 +58,7 @@ class GnuCashSQL(BaseOutput):
self._warn_about_backslashes(
{
"date": fmt.format_date("1970-01-01"),
"time": fmt.time,
"base": base,
"quote": quote,
@ -135,7 +136,7 @@ class GnuCashSQL(BaseOutput):
logging.warning(
f"Before running this SQL, check the formatting of the "
f"{self._english_join(hits)} strings. "
f"SQLite treats backslahes in strings as plain characters, but "
f"SQLite treats backslashes in strings as plain characters, but "
f"MariaDB/MySQL and PostgreSQL may interpret them as escape "
f"codes."
)

View file

View file

@ -0,0 +1,44 @@
from decimal import Decimal
import pytest
from pricehist.format import Format
from pricehist.outputs.beancount import Beancount
from pricehist.price import Price
from pricehist.series import Series
@pytest.fixture
def out():
return Beancount()
@pytest.fixture
def series():
prices = [
Price("2021-01-01", Decimal("24139.4648")),
Price("2021-01-02", Decimal("26533.576")),
Price("2021-01-03", Decimal("27001.2846")),
]
return Series("BTC", "EUR", "close", "2021-01-01", "2021-01-03", prices)
def test_format_basics(out, series, mocker):
source = mocker.MagicMock()
result = out.format(series, source, Format())
assert result == (
"2021-01-01 price BTC 24139.4648 EUR\n"
"2021-01-02 price BTC 26533.576 EUR\n"
"2021-01-03 price BTC 27001.2846 EUR\n"
)
def test_format_custom(out, series, mocker):
source = mocker.MagicMock()
fmt = Format(base="XBT", quote="EURO", thousands=".", decimal=",", datesep="/")
result = out.format(series, source, fmt)
assert result == (
"2021/01/01 price XBT 24.139,4648 EURO\n"
"2021/01/02 price XBT 26.533,576 EURO\n"
"2021/01/03 price XBT 27.001,2846 EURO\n"
)

View file

@ -0,0 +1,50 @@
from decimal import Decimal
import pytest
from pricehist.format import Format
from pricehist.outputs.csv import CSV
from pricehist.price import Price
from pricehist.series import Series
@pytest.fixture
def out():
return CSV()
@pytest.fixture
def series():
prices = [
Price("2021-01-01", Decimal("24139.4648")),
Price("2021-01-02", Decimal("26533.576")),
Price("2021-01-03", Decimal("27001.2846")),
]
return Series("BTC", "EUR", "close", "2021-01-01", "2021-01-03", prices)
def test_format_basics(out, series, mocker):
source = mocker.MagicMock()
source.id = mocker.MagicMock(return_value="sourceid")
result = out.format(series, source, Format())
assert result == (
"date,base,quote,amount,source,type\n"
"2021-01-01,BTC,EUR,24139.4648,sourceid,close\n"
"2021-01-02,BTC,EUR,26533.576,sourceid,close\n"
"2021-01-03,BTC,EUR,27001.2846,sourceid,close\n"
)
def test_format_custom(out, series, mocker):
source = mocker.MagicMock()
source.id = mocker.MagicMock(return_value="sourceid")
fmt = Format(
base="XBT", quote="", thousands=".", decimal=",", datesep="/", csvdelim="/"
)
result = out.format(series, source, fmt)
assert result == (
"date/base/quote/amount/source/type\n"
'"2021/01/01"/XBT/€/24.139,4648/sourceid/close\n'
'"2021/01/02"/XBT/€/26.533,576/sourceid/close\n'
'"2021/01/03"/XBT/€/27.001,2846/sourceid/close\n'
)

View file

@ -0,0 +1,140 @@
import dataclasses
import logging
import re
from decimal import Decimal
import pytest
from pricehist.format import Format
from pricehist.outputs.gnucashsql import GnuCashSQL
from pricehist.price import Price
from pricehist.series import Series
@pytest.fixture
def out():
return GnuCashSQL()
@pytest.fixture
def series():
prices = [
Price("2021-01-01", Decimal("24139.4648")),
Price("2021-01-02", Decimal("26533.576")),
Price("2021-01-03", Decimal("27001.2846")),
]
return Series("BTC", "EUR", "close", "2021-01-01", "2021-01-03", prices)
@pytest.fixture
def src(mocker):
source = mocker.MagicMock()
source.id = mocker.MagicMock(return_value="coindesk")
return source
def test_format_base_and_quote(out, series, src):
result = out.format(series, src, Format())
base, quote = re.findall(r"WHERE mnemonic = (.*) LIMIT", result, re.MULTILINE)
assert base == "'BTC'"
assert quote == "'EUR'"
def test_format_new_price_values(out, series, src):
result = out.format(series, src, Format())
values = re.search(
r"\(guid, date, base, quote, source, type, "
r"value_num, value_denom\) VALUES\n([^;]*);",
result,
re.MULTILINE,
)[1]
assert values == (
"('0c4c01bd0a252641b806ce46f716f161', '2021-01-01 00:00:00', "
"'BTC', 'EUR', 'coindesk', 'close', 241394648, 10000),\n"
"('47f895ddfcce18e2421387e0e1b636e9', '2021-01-02 00:00:00', "
"'BTC', 'EUR', 'coindesk', 'close', 26533576, 1000),\n"
"('0d81630c4ac50c1b9b7c8211bf99c94e', '2021-01-03 00:00:00', "
"'BTC', 'EUR', 'coindesk', 'close', 270012846, 10000)\n"
)
def test_format_customized(out, series, src):
fmt = Format(
base="XBT",
quote="EURO",
datesep="/",
time="23:59:59",
)
result = out.format(series, src, fmt)
base, quote = re.findall(r"WHERE mnemonic = (.*) LIMIT", result, re.MULTILINE)
values = re.search(
r"\(guid, date, base, quote, source, type, "
r"value_num, value_denom\) VALUES\n([^;]*);",
result,
re.MULTILINE,
)[1]
assert base == "'XBT'"
assert quote == "'EURO'"
assert values == (
"('448173eef5dea23cea9ff9d5e8c7b07e', '2021/01/01 23:59:59', "
"'XBT', 'EURO', 'coindesk', 'close', 241394648, 10000),\n"
"('b6c0f4474c91c50e8f65b47767f874ba', '2021/01/02 23:59:59', "
"'XBT', 'EURO', 'coindesk', 'close', 26533576, 1000),\n"
"('2937c872cf0672863e11b9f46ee41e09', '2021/01/03 23:59:59', "
"'XBT', 'EURO', 'coindesk', 'close', 270012846, 10000)\n"
)
def test_format_escaping_of_strings(out, series, src):
result = out.format(series, src, Format(base="B'tc''n"))
base, quote = re.findall(r"WHERE mnemonic = (.*) LIMIT", result, re.MULTILINE)
assert base == "'B''tc''''n'"
def test_format_insert_commented_out_if_no_values(out, series, src):
empty_series = dataclasses.replace(series, prices=[])
result = out.format(empty_series, src, Format())
(
"-- INSERT INTO new_prices (guid, date, base, quote, source, type, "
"value_num, value_denom) VALUES\n"
"-- \n"
"-- ;\n"
) in result
def test_format_warns_about_backslash(out, series, src, caplog):
with caplog.at_level(logging.WARNING):
out.format(series, src, Format(quote="EU\\RO"))
r = caplog.records[0]
assert r.levelname == "WARNING"
assert "backslashes in strings" in r.message
def test__english_join_other_cases(out):
assert out._english_join([]) == ""
assert out._english_join(["one"]) == "one"
assert out._english_join(["one", "two"]) == "one and two"
assert out._english_join(["one", "two", "three"]) == "one, two and three"
def test_format_warns_about_out_of_range_numbers(out, series, src, caplog):
too_big_numerator = Decimal("9223372036854.775808")
s = dataclasses.replace(series, prices=[Price("2021-01-01", too_big_numerator)])
with caplog.at_level(logging.WARNING):
out.format(s, src, Format())
r = caplog.records[0]
assert r.levelname == "WARNING"
assert "outside of the int64 range" in r.message
def test__rational_other_exponent_cases(out):
assert out._rational(Decimal("9223372036854e6")) == (
"9223372036854000000",
"1",
True,
)
assert out._rational(Decimal("9223372036854e-6")) == (
"9223372036854",
"1000000",
True,
)

View file

@ -0,0 +1,52 @@
from decimal import Decimal
import pytest
from pricehist.format import Format
from pricehist.outputs.ledger import Ledger
from pricehist.price import Price
from pricehist.series import Series
@pytest.fixture
def out():
return Ledger()
@pytest.fixture
def series():
prices = [
Price("2021-01-01", Decimal("24139.4648")),
Price("2021-01-02", Decimal("26533.576")),
Price("2021-01-03", Decimal("27001.2846")),
]
return Series("BTC", "EUR", "close", "2021-01-01", "2021-01-03", prices)
def test_format_basics(out, series, mocker):
source = mocker.MagicMock()
result = out.format(series, source, Format())
assert result == (
"P 2021-01-01 00:00:00 BTC 24139.4648 EUR\n"
"P 2021-01-02 00:00:00 BTC 26533.576 EUR\n"
"P 2021-01-03 00:00:00 BTC 27001.2846 EUR\n"
)
def test_format_custom(out, series, mocker):
source = mocker.MagicMock()
fmt = Format(
base="XBT",
quote="",
time="23:59:59",
thousands=".",
decimal=",",
symbol="left",
datesep="/",
)
result = out.format(series, source, fmt)
assert result == (
"P 2021/01/01 23:59:59 XBT €24.139,4648\n"
"P 2021/01/02 23:59:59 XBT €26.533,576\n"
"P 2021/01/03 23:59:59 XBT €27.001,2846\n"
)