Files @ 76f2707aacf7
Branch filter:

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

Brett Smith
hooks.ledger_entry: New hook to output Ledger entries.

This is roughly the smallest diff necessary to move output to a hook.
There's a lot of code reorganization that should still happen to bring it
better in line with this new structure.
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=[], stdout=None, stderr=None):
    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, stdout, stderr)

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)