diff --git a/tests/testutil.py b/tests/testutil.py new file mode 100644 index 0000000000000000000000000000000000000000..47368a38726592fca11b1ad98976e3a9afff9013 --- /dev/null +++ b/tests/testutil.py @@ -0,0 +1,80 @@ +"""Mock Beancount objects for testing""" +# Copyright © 2020 Brett Smith +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +import datetime + +import beancount.core.amount as bc_amount +import beancount.core.data as bc_data + +from decimal import Decimal + +FY_START_DATE = datetime.date(2020, 3, 1) +FY_MID_DATE = datetime.date(2020, 9, 1) + +def parse_date(s, fmt='%Y-%m-%d'): + return datetime.datetime.strptime(s, fmt).date() + +def Posting(account, number, + currency='USD', cost=None, price=None, flag=None, + **meta): + return bc_data.Posting( + account, + bc_amount.Amount(Decimal(number), currency), + cost, + price, + flag, + meta, + ) + +class Transaction: + def __init__(self, + date=FY_MID_DATE, flag='*', payee=None, + narration='', tags=None, links=None, postings=None, + **meta): + if isinstance(date, str): + date = parse_date(date) + self.date = date + self.flag = flag + self.payee = payee + self.narration = narration + self.tags = set(tags or '') + self.links = set(links or '') + self.postings = [] + self.meta = { + 'filename': '', + 'lineno': 0, + } + self.meta.update(meta) + for posting in postings: + self.add_posting(*posting) + + def add_posting(self, arg, *args, **kwargs): + """Add a posting to this transaction. Use any of these forms: + + txn.add_posting(account, number, …, kwarg=value, …) + txn.add_posting(account, number, …, posting_kwargs_dict) + txn.add_posting(posting_object) + """ + if kwargs: + posting = Posting(arg, *args, **kwargs) + elif args: + if isinstance(args[-1], dict): + kwargs = args[-1] + args = args[:-1] + posting = Posting(arg, *args, **kwargs) + else: + posting = arg + self.postings.append(posting)