Files @ c3fd55ec15b7
Branch filter:

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

Brett Smith
historical: Beancount can handle commas in amounts.

And having it looks nicer, is more consistent with our historical
books, is less code for me, and is no more trouble for the user.
import datetime
import decimal
import os

import babel
import pytest

from . import any_date, relpath

import oxrlib.cache
import oxrlib.config
import oxrlib.loaders

INI_DIR_PATH = relpath('config_ini')

def config_from(ini_filename, arglist):
    ini_path = INI_DIR_PATH / ini_filename
    return oxrlib.config.Configuration(['--config-file', ini_path.as_posix()] + arglist)

def test_full_config(any_date):
    config = config_from('full.ini', ['historical', any_date.isoformat()])
    loaders = config.get_loaders().loaders
    assert type(loaders[0]) is oxrlib.loaders.FileCache
    assert type(loaders[1]) is oxrlib.loaders.OXRAPIRequest
    assert len(loaders) == 2
    assert type(config.cache) is oxrlib.cache.CacheWriter

def test_incomplete_config(any_date):
    config = config_from('incomplete.ini', ['historical', any_date.isoformat()])
    assert not config.get_loaders().loaders

def test_empty_config(any_date):
    config = config_from(os.devnull, ['historical', any_date.isoformat()])
    assert not config.get_loaders().loaders

@pytest.mark.parametrize('ini_filename,expected_currency,use_switch', [
    (os.devnull, 'USD', False),
    ('full.ini', 'INI', False),
    ('full.ini', 'EUR', True),
])
def test_historical_default_base(ini_filename, expected_currency, use_switch, any_date):
    arglist = ['historical']
    if use_switch:
        arglist.extend(['--base', expected_currency])
    arglist.append(any_date.isoformat())
    config = config_from(ini_filename, arglist)
    assert config.args.base == expected_currency

@pytest.mark.parametrize('amount,from_curr,prep1,to_curr,prep2,from_date', [
    (None, 'JPY', None, None, None, None),
    (None, 'gbp', None, 'Aud', None, None),
    (None, 'CHF', 'to', 'eur', None, None),
    (decimal.Decimal('1000'), 'chf', None, None, None, None),
    (decimal.Decimal('999'), 'Eur', None, 'Chf', None, None),
    (decimal.Decimal('12.34'), 'gbp', 'IN', 'eur', None, None),
    (None, 'JPY', None, None, None, '12-15'),
    (None, 'gbp', None, 'Aud', 'From', '12.15'),
    (None, 'CHF', 'to', 'eur', 'from', '15'),
    (decimal.Decimal('1000'), 'chf', None, None, None, '12-15'),
    (decimal.Decimal('999'), 'Eur', None, 'Chf', None, '2016.12.15'),
    (decimal.Decimal('12.34'), 'gbp', 'IN', 'eur', 'from', '2016-12-15'),
])
def test_historical_argparsing_success(amount, from_curr, prep1, to_curr, prep2, from_date, any_date):
    oxrlib.config.Configuration.TODAY = datetime.date(2017, 1, 1)
    # This locale's currency should not be used in any test cases above.
    oxrlib.config.Configuration.LOCALE = babel.core.Locale('en', 'IN')
    arglist = ['historical', any_date.isoformat()]
    arglist.extend(str(s) for s in [amount, from_curr, prep1, to_curr, prep2, from_date]
                   if s is not None)
    config = config_from(os.devnull, arglist)
    expect_to_curr = 'INR' if to_curr is None else to_curr.upper()
    assert config.args.amount == amount
    assert config.args.from_currency == from_curr.upper()
    assert config.args.to_currency == expect_to_curr
    expect_from_date = None if from_date is None else datetime.date(2016, 12, 15)
    assert config.args.from_date == expect_from_date

@pytest.mark.parametrize('arglist', [
    ['100'],
    ['120', 'dollars'],
    ['to', '42', 'usd'],
    ['99', 'usd', 'minus', 'jpy'],
    ['usdjpy'],
    ['44', 'eur', 'in', 'chf', 'pronto'],
    ['eur', 'into'],
    ['50', 'jpy', 'in'],
    ['115', 'usd', 'in', '12-15'],
    ['125', 'jpy', 'from', 'chf'],
    ['135', 'chf', 'eur', 'gbp'],
    ['145', 'brl', '12-16', '2020-12-18'],
])
def test_historical_argparsing_failure(arglist, any_date):
    arglist = ['historical', any_date.isoformat()] + arglist
    try:
        config = config_from(os.devnull, arglist)
    except SystemExit:
        pass
    else:
        assert not vars(config.args), "bad arglist succeeded"

@pytest.mark.parametrize('date_s,expect_year,expect_month,expect_day', [
    ('5', 1965, 7, 5),
    ('05', 1965, 7, 5),
    ('14', 1965, 7, 14),
    ('15', 1965, 7, 15),
    ('16', 1965, 6, 16),
    ('3-6', 1965, 3, 6),
    ('11.10', 1964, 11, 10),
    ('07-14', 1965, 7, 14),
    ('07/15', 1965, 7, 15),
    ('7.16', 1964, 7, 16),
    ('917/12/12', 917, 12, 12),
    ('2017-11-1', 2017, 11, 1),
])
def test_good_date_parsing(date_s, expect_year, expect_month, expect_day):
    oxrlib.config.Configuration.TODAY = datetime.date(1965, 7, 15)
    config = config_from(os.devnull, ['historical', date_s])
    actual_date = config.args.date
    assert actual_date.year == expect_year
    assert actual_date.month == expect_month
    assert actual_date.day == expect_day

@pytest.mark.parametrize('date_s', [
    '99',
    '8-88',
    '77-7',
    '0xf-1-2',
    '0b1-3-4',
    '2017/5.9',
    '2018-6/10',
    '1-2-3-4',
    '12/11/10',
])
def test_bad_date_parsing(date_s):
    try:
        config = config_from(os.devnull, ['historical', date_s])
    except SystemExit:
        pass
    else:
        assert not config.args.date, "date parsed from {!r}".format(date_s)

def test_ambiguous_arglist_failure():
    try:
        # It's ambiguous if "2" is "the 2nd" or "2 EUR".
        config = config_from(os.devnull, ['historical', '2', 'eur'])
    except SystemExit:
        pass
    else:
        assert not config.args, "ambiguous args parsed"