Basic tests for cli().
This commit is contained in:
parent
66e95c1ac4
commit
0ddaf5893b
2 changed files with 176 additions and 8 deletions
|
@ -10,7 +10,7 @@ from pricehist.format import Format
|
|||
from pricehist.series import Series
|
||||
|
||||
|
||||
def cli(argv=sys.argv, output_file=sys.stdout):
|
||||
def cli(argv=sys.argv):
|
||||
start_time = datetime.now()
|
||||
|
||||
logger.init()
|
||||
|
@ -25,20 +25,20 @@ def cli(argv=sys.argv, output_file=sys.stdout):
|
|||
|
||||
try:
|
||||
if args.version:
|
||||
print(f"pricehist {__version__}", file=output_file)
|
||||
print(f"pricehist {__version__}")
|
||||
elif args.command == "sources":
|
||||
result = sources.formatted()
|
||||
print(result, file=output_file)
|
||||
print(result)
|
||||
elif args.command == "source" and args.symbols:
|
||||
result = sources.by_id[args.source].format_symbols()
|
||||
print(result, file=output_file, end="")
|
||||
print(result, end="")
|
||||
elif args.command == "source" and args.search:
|
||||
result = sources.by_id[args.source].format_search(args.search)
|
||||
print(result, file=output_file, end="")
|
||||
print(result, end="")
|
||||
elif args.command == "source":
|
||||
total_width = shutil.get_terminal_size().columns
|
||||
result = sources.by_id[args.source].format_info(total_width)
|
||||
print(result, file=output_file)
|
||||
print(result)
|
||||
elif args.command == "fetch":
|
||||
source = sources.by_id[args.source]
|
||||
output = outputs.by_type[args.output]
|
||||
|
@ -60,9 +60,9 @@ def cli(argv=sys.argv, output_file=sys.stdout):
|
|||
)
|
||||
fmt = Format.fromargs(args)
|
||||
result = fetch(series, source, output, args.invert, args.quantize, fmt)
|
||||
print(result, end="", file=output_file)
|
||||
print(result, end="")
|
||||
else:
|
||||
parser.print_help(file=sys.stderr)
|
||||
parser.print_help()
|
||||
except BrokenPipeError:
|
||||
logging.debug("The output pipe was closed early.")
|
||||
finally:
|
||||
|
|
168
tests/pricehist/test_cli.py
Normal file
168
tests/pricehist/test_cli.py
Normal file
|
@ -0,0 +1,168 @@
|
|||
import argparse
|
||||
import logging
|
||||
from decimal import Decimal
|
||||
|
||||
import pytest
|
||||
|
||||
from pricehist import __version__, cli, sources
|
||||
|
||||
|
||||
def w(string):
|
||||
return string.split(" ")
|
||||
|
||||
|
||||
def test_valid_pair():
|
||||
assert cli.valid_pair("BTC/AUD") == ("BTC", "AUD")
|
||||
assert cli.valid_pair("BTC/AUD/ignored") == ("BTC", "AUD")
|
||||
assert cli.valid_pair("SYM") == ("SYM", "")
|
||||
assert cli.valid_pair("SYM/") == ("SYM", "")
|
||||
with pytest.raises(argparse.ArgumentTypeError):
|
||||
cli.valid_pair("/SYM")
|
||||
with pytest.raises(argparse.ArgumentTypeError):
|
||||
cli.valid_pair("")
|
||||
|
||||
|
||||
def test_valid_date():
|
||||
assert cli.valid_date("today") == cli.today()
|
||||
assert cli.valid_date("2021-12-30") == "2021-12-30"
|
||||
with pytest.raises(argparse.ArgumentTypeError) as e:
|
||||
cli.valid_date("2021-12-40")
|
||||
assert "Not a valid" in str(e.value)
|
||||
|
||||
|
||||
def test_valid_date_before():
|
||||
assert cli.valid_date_before("2021-12-30") == "2021-12-29"
|
||||
with pytest.raises(argparse.ArgumentTypeError) as e:
|
||||
cli.valid_date_before("2021-12-40")
|
||||
assert "Not a valid" in str(e.value)
|
||||
|
||||
|
||||
def test_valid_date_after():
|
||||
assert cli.valid_date_after("2021-12-30") == "2021-12-31"
|
||||
with pytest.raises(argparse.ArgumentTypeError) as e:
|
||||
cli.valid_date_after("2021-12-40")
|
||||
assert "Not a valid" in str(e.value)
|
||||
|
||||
|
||||
def test_valid_char():
|
||||
assert cli.valid_char(",") == ","
|
||||
with pytest.raises(argparse.ArgumentTypeError):
|
||||
cli.valid_char("")
|
||||
with pytest.raises(argparse.ArgumentTypeError):
|
||||
cli.valid_char("12")
|
||||
|
||||
|
||||
def test_cli_no_args_shows_usage(capfd):
|
||||
cli.cli(w("pricehist"))
|
||||
out, err = capfd.readouterr()
|
||||
assert "usage: pricehist" in out
|
||||
assert "optional arguments:" in out
|
||||
assert "commands:" in out
|
||||
|
||||
|
||||
def test_cli_help_shows_usage_and_exits(capfd):
|
||||
with pytest.raises(SystemExit) as e:
|
||||
cli.cli(w("pricehist -h"))
|
||||
assert e.value.code == 0
|
||||
out, err = capfd.readouterr()
|
||||
assert "usage: pricehist" in out
|
||||
assert "optional arguments:" in out
|
||||
assert "commands:" in out
|
||||
|
||||
|
||||
def test_cli_verbose(capfd, mocker):
|
||||
cli.cli(w("pricehist --verbose"))
|
||||
out, err = capfd.readouterr()
|
||||
assert "Ended pricehist run at" in err
|
||||
|
||||
|
||||
def test_cli_version(capfd):
|
||||
cli.cli(w("pricehist --version"))
|
||||
out, err = capfd.readouterr()
|
||||
assert f"pricehist {__version__}\n" == out
|
||||
|
||||
|
||||
def test_cli_sources(capfd):
|
||||
cli.cli(w("pricehist sources"))
|
||||
out, err = capfd.readouterr()
|
||||
for source_id in sources.by_id.keys():
|
||||
assert source_id in out
|
||||
|
||||
|
||||
def test_cli_source(capfd):
|
||||
expected = sources.by_id["ecb"].format_info() + "\n"
|
||||
cli.cli(w("pricehist source ecb"))
|
||||
out, err = capfd.readouterr()
|
||||
assert out == expected
|
||||
|
||||
|
||||
def test_cli_source_symbols(capfd, mocker):
|
||||
sources.by_id["ecb"].symbols = mocker.MagicMock(
|
||||
return_value=[("EUR/AUD", "Euro against Australian Dollar")]
|
||||
)
|
||||
cli.cli(w("pricehist source ecb --symbols"))
|
||||
out, err = capfd.readouterr()
|
||||
assert out == "EUR/AUD Euro against Australian Dollar\n"
|
||||
|
||||
|
||||
def test_cli_source_search(capfd, mocker):
|
||||
sources.by_id["alphavantage"].search = mocker.MagicMock(
|
||||
return_value=[("TSLA", "Tesla Inc, Equity, United States, USD")]
|
||||
)
|
||||
cli.cli(w("pricehist source alphavantage --search TSLA"))
|
||||
out, err = capfd.readouterr()
|
||||
assert out == "TSLA Tesla Inc, Equity, United States, USD\n"
|
||||
|
||||
|
||||
def test_cli_source_fetch(capfd, mocker):
|
||||
formatted_result = "P 2021-01-01 00:00:00 BTC 24139.4648 EUR\n"
|
||||
cli.fetch = mocker.MagicMock(return_value=formatted_result)
|
||||
argv = w("pricehist fetch coindesk BTC/EUR -s 2021-01-01 -e 2021-01-01 -o ledger")
|
||||
cli.cli(argv)
|
||||
out, err = capfd.readouterr()
|
||||
assert out == formatted_result
|
||||
|
||||
|
||||
def test_cli_source_fetch_invalid_start(capfd, mocker):
|
||||
argv = w("pricehist fetch coindesk BTC/EUR -s 2021-01-01 -e 2020-12-01")
|
||||
with pytest.raises(SystemExit) as e:
|
||||
cli.cli(argv)
|
||||
assert e.value.code != 0
|
||||
out, err = capfd.readouterr()
|
||||
assert "end date '2020-12-01' preceeds the start date" in err
|
||||
|
||||
|
||||
def test_cli_source_fetch_invalid_type(capfd, mocker):
|
||||
argv = w("pricehist fetch coindesk BTC/EUR -t notype")
|
||||
with pytest.raises(SystemExit) as e:
|
||||
cli.cli(argv)
|
||||
assert e.value.code != 0
|
||||
out, err = capfd.readouterr()
|
||||
assert "price type 'notype' is not recognized" in err
|
||||
|
||||
|
||||
def test_cli_source_fetch_sets_source_defaults(mocker):
|
||||
cli.fetch = mocker.MagicMock(return_value="")
|
||||
cli.cli(w("pricehist fetch coindesk BTC/EUR"))
|
||||
captured_series = cli.fetch.call_args.args[0]
|
||||
assert captured_series.start == sources.by_id["coindesk"].start()
|
||||
assert captured_series.type == sources.by_id["coindesk"].types()[0]
|
||||
|
||||
|
||||
def test_cli_source_fetch_normalizes_symbols(mocker):
|
||||
cli.fetch = mocker.MagicMock(return_value="")
|
||||
cli.cli(w("pricehist fetch coindesk btc/eur"))
|
||||
captured_series = cli.fetch.call_args.args[0]
|
||||
assert captured_series.base == "BTC"
|
||||
assert captured_series.quote == "EUR"
|
||||
|
||||
|
||||
def test_cli_source_fetch_handles_brokenpipeerror(caplog, mocker):
|
||||
cli.fetch = mocker.MagicMock(side_effect=BrokenPipeError())
|
||||
cli.cli(w("pricehist fetch coindesk BTC/EUR --verbose"))
|
||||
assert any(
|
||||
[
|
||||
"DEBUG" == r.levelname and "output pipe was closed early" in r.message
|
||||
for r in caplog.records
|
||||
]
|
||||
)
|
Loading…
Add table
Reference in a new issue