Files @ 992c91fc90de
Branch filter:

Location: NPO-Accounting/oxrlib/tests/test_historical.py

Brett Smith
config: Nicer implementation of date parsing.

Keeps less local state through the function, to reduce the risk of that
state getting inconsistent.
import argparse
import decimal
import io
import json

import pytest

from . import any_date, relpath

import oxrlib.commands.historical as oxrhist

class FakeResponder:
    def __init__(self, response_path):
        self.response_path = response_path

    def _respond(self, *args, **kwargs):
        return open(self.response_path)

    def __getattr__(self, name):
        return self._respond

    def should_cache(self):
        return False


class FakeConfig:
    def __init__(self, responder, argvars=None):
        self.responder = responder
        self.args = argparse.Namespace()
        if argvars is not None:
            for key in argvars:
                setattr(self.args, key, argvars[key])

    def get_loaders(self):
        return self.responder


output = pytest.fixture(lambda: io.StringIO())

@pytest.fixture
def historical1_responder():
    return FakeResponder(relpath('historical1.json').as_posix())

def build_config(
        responder,
        date=None,
        amount=None,
        from_currency=None,
        to_currency=None,
        ledger=False,
        signed_currencies=None,
        base='USD',
):
    return FakeConfig(responder, {
        'date': any_date() if date is None else date,
        'base': base,
        'amount': None if amount is None else decimal.Decimal(amount),
        'from_currency': from_currency,
        'to_currency': base if to_currency is None else to_currency,
        'ledger': ledger,
        'signed_currencies': [base] if signed_currencies is None else signed_currencies,
    })

def lines_from_run(config, output):
    oxrhist.run(config, output, output)
    output.seek(0)
    return iter(output)

def test_rate_list(historical1_responder, output):
    config = build_config(historical1_responder)
    lines = lines_from_run(config, output)
    assert next(lines).startswith('1 AED = 0.27229')
    assert next(lines) == '1 USD = 3.67246 AED\n'
    assert next(lines).startswith('1 ALL = 0.0069189')
    assert next(lines) == '1 USD = 144.529793 ALL\n'
    assert next(lines).startswith('1 ANG = 0.55865')
    assert next(lines) == '1 USD = 1.79 ANG\n'

def test_one_rate(historical1_responder, output):
    config = build_config(historical1_responder, from_currency='ANG')
    lines = lines_from_run(config, output)
    assert next(lines).startswith('1 ANG = 0.55865')
    assert next(lines) == '1 USD = 1.79 ANG\n'
    assert next(lines, None) is None

def test_conversion(historical1_responder, output):
    config = build_config(historical1_responder, amount=10, from_currency='AED')
    lines = lines_from_run(config, output)
    assert next(lines) == '10.00 AED = 2.72 USD\n'
    assert next(lines, None) is None

def test_back_conversion(historical1_responder, output):
    config = build_config(historical1_responder,
                          amount=2, from_currency='USD', to_currency='ALL')
    lines = lines_from_run(config, output)
    assert next(lines) == '2.00 USD = 289 ALL\n'
    assert next(lines, None) is None

def test_ledger_rate(historical1_responder, output):
    config = build_config(historical1_responder, from_currency='ANG', ledger=True)
    lines = lines_from_run(config, output)
    assert next(lines) == '1 ANG {=$0.55866} @ $0.55866\n'
    assert next(lines) == '1 USD {=1.79 ANG} @ 1.79 ANG\n'
    assert next(lines, None) is None

def test_ledger_conversion(historical1_responder, output):
    config = build_config(historical1_responder, from_currency='ALL', amount=300, ledger=True)
    lines = lines_from_run(config, output)
    assert next(lines) == '300 ALL {=$0.006919} @ $0.006919\n'
    assert next(lines) == '$2.08\n'
    assert next(lines, None) is None

def test_signed_currencies(historical1_responder, output):
    config = build_config(historical1_responder, from_currency='AED',
                          ledger=True, signed_currencies=['EUR'])
    lines = lines_from_run(config, output)
    assert next(lines) == '1 AED {=0.2723 USD} @ 0.2723 USD\n'
    assert next(lines) == '1 USD {=3.67246 AED} @ 3.67246 AED\n'
    assert next(lines, None) is None