"""Test Posting methods""" # Copyright © 2020 Brett Smith # License: AGPLv3-or-later WITH Beancount-Plugin-Additional-Permission-1.0 # # Full copyright and licensing details can be found at toplevel file # LICENSE.txt in the repository. import pytest from . import testutil from beancount.core import data as bc_data from conservancy_beancount import data @pytest.fixture def simple_txn(index=None, key=None): return testutil.Transaction(note='txn note', postings=[ ('Assets:Cash', 5), ('Income:Donations', -5, {'note': 'donation love', 'extra': 'Extra'}), ]) def test_from_beancount(): txn = testutil.Transaction(payee='Smith-Dakota', postings=[ ('Income:Donations', -50), ('Assets:Cash', 50, {'receipt': 'cash-donation.pdf'}), ]) post = data.Posting.from_beancount(txn, 1) # We don't just want to assert isinstance(post.attr, data.SomeClass); # we also want to double-check that attributes were instantiated correctly. assert post.account.is_under('Assets:Cash') assert post.meta['receipt'] == 'cash-donation.pdf' assert post.meta['entity'] == 'Smith-Dakota' assert post.meta.date == testutil.FY_MID_DATE def test_setting_metadata_propagates_to_source(simple_txn): src_post = simple_txn.postings[1] post = data.Posting.from_beancount(simple_txn, 1) post.meta['edited'] = 'yes' assert src_post.meta['edited'] == 'yes' assert not isinstance(src_post.meta, data.PostingMeta) def test_deleting_metadata_propagates_to_source(simple_txn): post = data.Posting.from_beancount(simple_txn, 1) del post.meta['extra'] assert 'extra' not in simple_txn.postings[1].meta def test_from_txn(simple_txn): for source, post in zip(simple_txn.postings, data.Posting.from_txn(simple_txn)): assert all(source[x] == post[x] for x in range(len(source) - 1)) assert isinstance(post.account, data.Account) assert post.meta['note'] # Only works with PostingMeta def test_from_entries_two_txns(simple_txn): entries = [simple_txn, simple_txn] sources = [post for txn in entries for post in txn.postings] for source, post in zip(sources, data.Posting.from_entries(entries)): assert all(source[x] == post[x] for x in range(len(source) - 1)) assert isinstance(post.account, data.Account) assert post.meta['note'] # Only works with PostingMeta def test_from_entries_mix_txns_and_other_directives(simple_txn): meta = { 'filename': __file__, 'lineno': 75, } entries = [ bc_data.Commodity(meta, testutil.FY_START_DATE, 'EUR'), bc_data.Commodity(meta, testutil.FY_START_DATE, 'USD'), simple_txn, ] for source, post in zip(simple_txn.postings, data.Posting.from_entries(entries)): assert all(source[x] == post[x] for x in range(len(source) - 1)) assert isinstance(post.account, data.Account) assert post.meta['note'] # Only works with PostingMeta @pytest.mark.parametrize('cost_num', [105, 110, 115]) def test_at_cost(cost_num): post = data.Posting( 'Income:Donations', testutil.Amount(25, 'EUR'), testutil.Cost(cost_num, 'JPY'), None, '*', None, ) assert post.at_cost() == testutil.Amount(25 * cost_num, 'JPY') def test_at_cost_no_cost(): amount = testutil.Amount(25, 'EUR') post = data.Posting( 'Income:Donations', amount, None, None, '*', None, ) assert post.at_cost() == amount