2017-10-22 17:38:53 +00:00
|
|
|
import configparser
|
|
|
|
import datetime
|
|
|
|
import decimal
|
|
|
|
import pathlib
|
|
|
|
|
|
|
|
import pytest
|
2017-11-09 22:19:36 +00:00
|
|
|
from import2ledger import errors, template
|
2017-10-22 17:38:53 +00:00
|
|
|
|
|
|
|
from . import DATA_DIR, normalize_whitespace
|
|
|
|
|
|
|
|
DATE = datetime.date(2015, 3, 14)
|
|
|
|
|
|
|
|
config = configparser.ConfigParser(comment_prefixes='#')
|
|
|
|
with pathlib.Path(DATA_DIR, 'templates.ini').open() as conffile:
|
|
|
|
config.read_file(conffile)
|
|
|
|
|
|
|
|
def template_from(section_name, *args, **kwargs):
|
|
|
|
return template.Template(config[section_name]['template'], *args, **kwargs)
|
|
|
|
|
|
|
|
def assert_easy_render(tmpl, entity, amount, currency, expect_date, expect_amt):
|
|
|
|
rendered = tmpl.render(entity, decimal.Decimal(amount), currency, DATE)
|
|
|
|
lines = [normalize_whitespace(s) for s in rendered.splitlines()]
|
|
|
|
assert lines == [
|
|
|
|
"",
|
|
|
|
"{} {}".format(expect_date, entity),
|
|
|
|
" Accrued:Accounts Receivable " + expect_amt,
|
|
|
|
" Income:Donations " + expect_amt.replace(amount, "-" + amount),
|
|
|
|
]
|
|
|
|
|
|
|
|
def test_easy_template():
|
|
|
|
tmpl = template_from('Simplest')
|
|
|
|
assert_easy_render(tmpl, 'JJ', '5.99', 'CAD', '2015/03/14', '5.99 CAD')
|
|
|
|
|
|
|
|
def test_date_formatting():
|
|
|
|
tmpl = template_from('Simplest', date_fmt='%Y-%m-%d')
|
|
|
|
assert_easy_render(tmpl, 'KK', '6.99', 'CAD', '2015-03-14', '6.99 CAD')
|
|
|
|
|
|
|
|
def test_currency_formatting():
|
|
|
|
tmpl = template_from('Simplest', signed_currencies=['USD'])
|
|
|
|
assert_easy_render(tmpl, 'CC', '7.99', 'USD', '2015/03/14', '$7.99')
|
|
|
|
|
|
|
|
def test_complex_template():
|
|
|
|
template_vars = {
|
|
|
|
'entity': 'T-T',
|
2017-11-09 21:16:20 +00:00
|
|
|
'program': 'Spectrum Defense',
|
2017-10-22 17:38:53 +00:00
|
|
|
'txid': 'ABCDEF',
|
|
|
|
}
|
|
|
|
tmpl = template_from('Complex', date_fmt='%Y-%m-%d', signed_currencies=['USD'])
|
|
|
|
rendered = tmpl.render('TT', decimal.Decimal('125.50'), 'USD', DATE, **template_vars)
|
|
|
|
lines = [normalize_whitespace(s) for s in rendered.splitlines()]
|
|
|
|
assert lines == [
|
|
|
|
"",
|
|
|
|
"2015-03-14 TT",
|
|
|
|
" ;Tag: Value",
|
|
|
|
" ;TransactionID: ABCDEF",
|
|
|
|
" Accrued:Accounts Receivable $125.50",
|
|
|
|
" ;Entity: Supplier",
|
2017-11-09 21:16:20 +00:00
|
|
|
" Income:Donations:Spectrum Defense $-119.85",
|
|
|
|
" ;Program: Spectrum Defense",
|
2017-10-22 17:38:53 +00:00
|
|
|
" ;Entity: T-T",
|
|
|
|
" Income:Donations:General $-5.65",
|
|
|
|
" ;Entity: T-T",
|
|
|
|
]
|
|
|
|
|
|
|
|
def test_balancing():
|
|
|
|
tmpl = template_from('FiftyFifty')
|
|
|
|
rendered = tmpl.render('FF', decimal.Decimal('1.01'), 'USD', DATE)
|
|
|
|
lines = [normalize_whitespace(s) for s in rendered.splitlines()]
|
|
|
|
assert lines == [
|
|
|
|
"",
|
|
|
|
"2015/03/14 FF",
|
|
|
|
" Accrued:Accounts Receivable 1.01 USD",
|
|
|
|
" Income:Donations -0.50 USD",
|
|
|
|
" Income:Sales -0.51 USD",
|
|
|
|
]
|
2017-11-09 17:18:20 +00:00
|
|
|
|
|
|
|
def test_multivalue():
|
|
|
|
tmpl = template_from('Multivalue')
|
|
|
|
rendered = tmpl.render('DD', decimal.Decimal('150.00'), 'USD', DATE,
|
|
|
|
tax=decimal.Decimal('12.50'))
|
|
|
|
lines = [normalize_whitespace(s) for s in rendered.splitlines()]
|
|
|
|
assert lines == [
|
|
|
|
"",
|
|
|
|
"2015/03/14 DD",
|
|
|
|
" Expenses:Taxes 12.50 USD",
|
2017-12-16 18:10:49 +00:00
|
|
|
" ;TaxAuthority: IRS",
|
2017-11-09 17:18:20 +00:00
|
|
|
" Accrued:Accounts Receivable 137.50 USD",
|
|
|
|
" Income:RBI -15.00 USD",
|
|
|
|
" Income:Donations -135.00 USD",
|
|
|
|
]
|
2017-11-09 22:19:36 +00:00
|
|
|
|
2017-12-16 18:10:49 +00:00
|
|
|
def test_zeroed_account_skipped():
|
|
|
|
tmpl = template_from('Multivalue')
|
|
|
|
rendered = tmpl.render('GG', decimal.Decimal('110.00'), 'USD', DATE,
|
|
|
|
tax=decimal.Decimal(0))
|
|
|
|
lines = [normalize_whitespace(s) for s in rendered.splitlines()]
|
|
|
|
assert lines == [
|
|
|
|
"",
|
|
|
|
"2015/03/14 GG",
|
|
|
|
" Accrued:Accounts Receivable 110.00 USD",
|
|
|
|
" Income:RBI -11.00 USD",
|
|
|
|
" Income:Donations -99.00 USD",
|
|
|
|
]
|
|
|
|
|
2017-11-09 22:19:36 +00:00
|
|
|
@pytest.mark.parametrize('amount_expr', [
|
|
|
|
'',
|
|
|
|
'name',
|
|
|
|
'-',
|
|
|
|
'()',
|
|
|
|
'+()',
|
|
|
|
'{}',
|
|
|
|
'{{}}',
|
|
|
|
'{()}',
|
|
|
|
'{name',
|
|
|
|
'name}',
|
|
|
|
'{42}',
|
|
|
|
'(5).real',
|
|
|
|
'{amount.real}',
|
|
|
|
'{amount.is_nan()}',
|
|
|
|
'{Decimal}',
|
|
|
|
'{FOO}',
|
|
|
|
])
|
|
|
|
def test_bad_amount_expression(amount_expr):
|
|
|
|
with pytest.raises(errors.UserInputError):
|
|
|
|
template.Template(" Income " + amount_expr)
|