Test outputs.
This commit is contained in:
parent
5d0c6aaf03
commit
78b622eade
6 changed files with 288 additions and 1 deletions
|
@ -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."
|
||||
)
|
||||
|
|
0
tests/pricehist/outputs/__init__.py
Normal file
0
tests/pricehist/outputs/__init__.py
Normal file
44
tests/pricehist/outputs/test_beancount.py
Normal file
44
tests/pricehist/outputs/test_beancount.py
Normal 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"
|
||||
)
|
50
tests/pricehist/outputs/test_csv.py
Normal file
50
tests/pricehist/outputs/test_csv.py
Normal 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'
|
||||
)
|
140
tests/pricehist/outputs/test_gnucashsql.py
Normal file
140
tests/pricehist/outputs/test_gnucashsql.py
Normal 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,
|
||||
)
|
52
tests/pricehist/outputs/test_ledger.py
Normal file
52
tests/pricehist/outputs/test_ledger.py
Normal 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"
|
||||
)
|
Loading…
Add table
Reference in a new issue