Files @ b41a7a99af17
Branch filter:

Location: NPO-Accounting/import2ledger/tests/test_config.py

Brett Smith
hooks: Filter entries by setting entry_data['_hook_cancel'] to True.

The current method only works for plain dicts and other simple mappings.
Mapping that may still contain items after .clear(), like ChainMap, can't
rely on the old method.
import contextlib
import datetime
import itertools
import logging
import os
import pathlib

START_DATE = datetime.date.today()

from unittest import mock

import pytest
from import2ledger import config, errors

from . import DATA_DIR

def config_from_file(path, arglist=[]):
    path = pathlib.Path(path)
    if not path.is_absolute():
        path = DATA_DIR / path
    arglist = ['-C', path.as_posix(), *arglist, os.devnull]
    return config.Configuration(arglist)

def test_defaults():
    config = config_from_file('test_config.ini', ['--sign', 'GBP', '-O', 'out_arg'])
    factory = mock.Mock(name='Template')
    template = config.get_template('one', 'Templates', factory)
    assert factory.called
    kwargs = factory.call_args[1]
    assert list(kwargs.pop('signed_currencies', '')) == ['GBP']
    assert kwargs == {
        'date_fmt': '%Y-%m-%d',
        'signed_currency_fmt': kwargs['signed_currency_fmt'],
        'template_name': 'one',
        'unsigned_currency_fmt': kwargs['unsigned_currency_fmt'],
    }

def test_template_parsing():
    config = config_from_file('test_config.ini')
    factory = mock.Mock(name='Template')
    template = config.get_template('two', 'Templates', factory)
    try:
        tmpl_s = factory.call_args[0][0]
    except IndexError as error:
        assert False, error
    assert "\n;Tag1: {value}\n" in tmpl_s
    assert "\nIncome:Donations  -{amount}\n" in tmpl_s
    assert "\n;IncomeTag: Donations\n" in tmpl_s

@pytest.mark.parametrize('arg_s', [None, '-', 'output.ledger'])
def test_output_path(arg_s):
    arglist = [] if arg_s is None else ['-O', arg_s]
    config = config_from_file(os.devnull, arglist)
    output_path = config.get_output_path()
    if (arg_s is None) or (arg_s == '-'):
        assert output_path is None
    else:
        assert output_path == pathlib.Path(arg_s)

def test_output_path_from_section():
    expected_path = pathlib.Path('Template.output')
    config = config_from_file('test_config.ini', ['-O', 'output.ledger'])
    assert config.get_output_path('Templates') == expected_path
    assert config.get_output_path() != expected_path
    with config.from_section('Templates'):
        assert config.get_output_path() == expected_path

@pytest.mark.parametrize('range_s,date_fmt', [
    (range_s.replace('/', sep), sep.join(['%Y', '%m', '%d']))
    for range_s, sep in itertools.product([
            '-',
            '2016/06/01-2016/06/30',
            '2016/06/01-',
            '-2016/06/30',
            ], '/-')
])
def test_date_in_want_range(range_s, date_fmt):
    config = config_from_file(os.devnull, ['--date-range=' + range_s, '--date-format', date_fmt])
    assert config.date_in_want_range(datetime.date(2016, 5, 31)) == range_s.startswith('-')
    assert config.date_in_want_range(datetime.date(2016, 6, 1))
    assert config.date_in_want_range(datetime.date(2016, 6, 30))
    assert config.date_in_want_range(datetime.date(2016, 7, 1)) == range_s.endswith('-')

@pytest.mark.parametrize('arglist,expect_date', [
    ([], None),
    (['-d', '2017-10-12'], datetime.date(2017, 10, 12)),
    (['-c', 'Date'], datetime.date(2017, 10, 8)),
])
def test_default_date(arglist, expect_date):
    config = config_from_file('test_config.ini', arglist)
    default_date = config.get_default_date()
    if expect_date is None:
        assert START_DATE <= default_date <= datetime.date.today()
    else:
        assert default_date == expect_date
    assert config.get_default_date('Date') == datetime.date(2017, 10, 8)

@pytest.mark.parametrize('level_s,expect_level', [
    (s, getattr(logging, s.upper()))
    for s in ['critical', 'debug', 'error', 'info', 'warning']
])
def test_loglevel(level_s, expect_level):
    config = config_from_file(os.devnull, ['--loglevel', level_s])
    assert config.get_loglevel() == expect_level

@contextlib.contextmanager
def bad_config(expect_input):
    with pytest.raises(errors.UserInputConfigurationError) as exc_info:
        yield exc_info
    assert exc_info.value.user_input == expect_input

def test_bad_default_date():
    date_s = '2017-10-06'
    with bad_config(date_s):
        config = config_from_file(os.devnull, ['--date', date_s])
        config.get_default_date()

def test_bad_loglevel():
    with bad_config('wraning'):
        config = config_from_file('test_config.ini', ['-c', 'Bad Loglevel'])
        config.get_loglevel()

def test_undefined_template():
    template_name = 'template nonexistent'
    config = config_from_file(os.devnull)
    with bad_config(template_name):
        config.get_template(template_name)