def test_segment_periods(self, entries, errors, options_map): """ 2014-01-01 open Assets:US:Investments:Cash 2014-01-01 open Assets:US:Bank:Checking 2014-01-01 price ACME 90.00 USD 2014-02-01 * "Deposit" Assets:US:Investments:Cash 10,000 USD Assets:US:Bank:Checking 2014-08-01 balance Assets:US:Investments:Cash 10,000 USD 2014-08-01 price ACME 100.00 USD """ self.assertFalse(errors) assets = {'Assets:US:Investments:Cash'} timeline = returns.segment_periods(entries, assets, assets) self.assertEqual(2, len(timeline)) empty = inventory.from_string('') self.assertEqual(timeline[0].begin, Snapshot(datetime.date(2014, 1, 1), empty)) self.assertEqual(timeline[0].end, Snapshot(datetime.date(2014, 2, 1), empty)) self.assertEqual( timeline[1].begin, Snapshot(datetime.date(2014, 2, 1), inventory.from_string('10000 USD'))) self.assertEqual( timeline[1].end, Snapshot(datetime.date(2014, 8, 1), inventory.from_string('10000 USD')))
def test_fill_residual_posting(self, entries, _, __): """ 2001-01-01 open Assets:Account1 2001-01-01 open Assets:Other 2014-01-01 * Assets:Account1 100.00 USD Assets:Other -100.00 USD 2014-01-02 * Assets:Account1 100.00 USD Assets:Other -100.00 USD 2014-01-03 * Assets:Account1 100.00 USD Assets:Other -100.0000001 USD 2014-01-04 * Assets:Account1 100.00 USD Assets:Other -112.69 CAD @ 0.8875 USD """ account = 'Equity:Rounding' entries = [entry for entry in entries if isinstance(entry, data.Transaction)] for index in 0, 1: entry = interpolate.fill_residual_posting(entries[index], account) self.assertEqualEntries([entries[index]], [entry]) residual = interpolate.compute_residual(entry.postings) self.assertTrue(residual.is_empty()) entry = interpolate.fill_residual_posting(entries[2], account) self.assertEqualEntries(""" 2014-01-03 * Assets:Account1 100.00 USD Assets:Other -100.0000001 USD Equity:Rounding 0.0000001 USD """, [entry]) residual = interpolate.compute_residual(entry.postings) # Note: The residual calcualtion ignores postings inserted by the # rounding account. self.assertFalse(residual.is_empty()) self.assertEqual(inventory.from_string('-0.0000001 USD'), residual) entry = interpolate.fill_residual_posting(entries[3], account) self.assertEqualEntries(""" 2014-01-04 * Assets:Account1 100.00 USD Assets:Other -112.69 CAD @ 0.8875 USD Equity:Rounding 0.012375 USD """, [entry]) residual = interpolate.compute_residual(entry.postings) # Same as above. self.assertFalse(residual.is_empty()) self.assertEqual(inventory.from_string('-0.012375 USD'), residual)
def test_compute_entry_context(self, entries, _, __): """ 2014-01-01 open Assets:Account1 2014-01-01 open Assets:Account2 2014-01-01 open Assets:Account3 2014-01-01 open Assets:Account4 2014-01-01 open Assets:Other 2014-02-10 * Assets:Account1 100.00 USD Assets:Other 2014-02-11 * Assets:Account2 80.00 USD Assets:Other 2014-02-12 * Assets:Account3 60.00 USD Assets:Account3 40.00 USD Assets:Other 2014-02-20 * #context Assets:Account1 5.00 USD Assets:Account2 -5.00 USD 2014-02-21 balance Assets:Account1 105.00 USD 2014-02-25 * Assets:Account3 5.00 USD Assets:Account4 -5.00 USD """ for entry in entries: if (isinstance(entry, data.Transaction) and entry.tags and 'context' in entry.tags): break balance_before, balance_after = interpolate.compute_entry_context( entries, entry) self.assertEqual(inventory.from_string('100.00 USD'), balance_before['Assets:Account1']) self.assertEqual(inventory.from_string('80.00 USD'), balance_before['Assets:Account2']) self.assertEqual(inventory.from_string('105.00 USD'), balance_after['Assets:Account1']) self.assertEqual(inventory.from_string('75.00 USD'), balance_after['Assets:Account2']) # Get the context for an entry that is not a Transaction and ensure that # the before and after context is the same. for entry in entries: if isinstance(entry, data.Balance): break balance_before, balance_after = interpolate.compute_entry_context( entries, entry) self.assertEqual(balance_before, balance_after)
def test_balance_by_account__no_end_date(self): # Test with no end date. balances, index = summarize.balance_by_account(self.entries) self.assertEqual(len(self.entries), index) self.assertEqual( { 'Assets:AccountA': inventory.from_string('11 USD'), 'Equity:Opening-Balances': inventory.from_string('-23 USD'), 'Assets:AccountB': inventory.from_string('12 USD') }, balances)
def test_balance_by_account__middle(self): # Test in the middle. balances, index = summarize.balance_by_account( self.entries, datetime.date(2014, 2, 10)) self.assertEqual(4, index) self.assertEqual( { 'Assets:AccountA': inventory.from_string('10 USD'), 'Equity:Opening-Balances': inventory.from_string('-10 USD'), }, balances)
def test_compute_balance(self): real_root = create_real([('Assets:US:Bank:Checking', '100 USD'), ('Assets:US:Bank:Savings', '200 USD'), ('Assets:US:Bank', '10 USD'), ('Liabilities:Bank:CreditCard', '-500 USD')]) balance = realization.compute_balance(real_root) self.assertEqual(inventory.from_string('-190 USD'), balance) balance = realization.compute_balance(realization.get(real_root, 'Assets:US:Bank')) self.assertEqual(inventory.from_string('310 USD'), balance)
def test_aggregated_group_by_visible(self): # GROUP-BY: 'account' is visible. self.check_sorted_query( self.INPUT, """ SELECT account, sum(position) as amount GROUP BY account; """, [ ('account', str), ('amount', inventory.Inventory), ], [ ('Assets:Bank:Checking', inventory.from_string('100.00 USD')), ('Expenses:Restaurant', inventory.from_string('-100.00 USD')), ])
def test_various(self): inv = inventory.from_string('100.00 USD') rdr = self.get(inv) self.assertEqual('100.00 USD', rdr.format(inv)) inv = inventory.from_string('5 HOOL {500.23 USD}') rdr = self.get(inv) self.assertEqual('5 HOOL {500.23 USD}', rdr.format(inv)) inv = inventory.from_string('5 HOOL {500.23 USD}, 12.3456 CAAD') rdr = self.get(inv) self.assertEqual( [' 5 HOOL {500.23 USD}', '12.3456 CAAD '], rdr.format(inv))
def test_inventory(self): itypes = [('balance', inventory.Inventory)] irows = [[inventory.from_string('10 HOOL {23.00 USD}')], [inventory.from_string('2.11 USD, 3.44 CAD')], [inventory.from_string('-2 HOOL {24.00 USD}, 5.66 CAD')]] atypes, arows = numberify.numberify_results(itypes, irows) self.assertEqual([('balance (HOOL)', Decimal), ('balance (CAD)', Decimal), ('balance (USD)', Decimal)], atypes) self.assertEqual([[D('10'), None, None], [None, D('3.44'), D('2.11')], [D('-2'), D('5.66'), None]], arows)
def test_aggregated_group_by_visible_order_by_non_aggregate_invisible( self): # GROUP-BY: 'account' and 'length(account)' are visible. # ORDER-BY: 'length(account)' is a non-aggregate and invisible. self.check_query( self.INPUT, """ SELECT account, sum(position) as amount GROUP BY account, length(account) ORDER BY length(account); """, [ ('account', str), ('amount', inventory.Inventory), ], [ ('Expenses:Restaurant', inventory.from_string('-100.00 USD')), ('Assets:Bank:Checking', inventory.from_string('100.00 USD')), ])
def test_creating__with_date(self): inv = inventory.Inventory() wash_calculator.book_position( inv, DD('2014-02-10'), position.from_string('10 HOOL {500 USD / 2014-02-11}')) self.assertEqual( inventory.from_string('10 HOOL {500 USD / 2014-02-11}'), inv)
def test_inventory(self): itypes = [('pos', inventory.Inventory)] irows = [(inventory.from_string(string), ) for string in self.input_amounts] atypes, arows = numberify.numberify_results(itypes, irows) self.assertEqual(self.expected_types, atypes) self.assertEqual(self.expected_rows, arows)
def test_compute_residual(self): # Try with two accounts. residual = interpolate.compute_residual([ P(None, "Assets:Bank:Checking", "105.50", "USD"), P(None, "Assets:Bank:Checking", "-194.50", "USD"), ]) self.assertEqual(inventory.from_string("-89 USD"), residual.units()) # Try with more accounts. residual = interpolate.compute_residual([ P(None, "Assets:Bank:Checking", "105.50", "USD"), P(None, "Assets:Bank:Checking", "-194.50", "USD"), P(None, "Assets:Bank:Investing", "5", "AAPL"), P(None, "Assets:Bank:Savings", "89.00", "USD"), ]) self.assertEqual(inventory.from_string("5 AAPL"), residual.units())
def test_reducing__sans_date__incomplete_amount(self): inv = inventory.Inventory() wash_calculator.book_position( inv, DD('2014-02-10'), position.from_string('10 HOOL {500 USD}')) wash_calculator.book_position( inv, DD('2014-02-10'), position.from_string('-7 HOOL {500 USD}')) self.assertEqual( inventory.from_string('3 HOOL {500 USD / 2014-02-10}'), inv)
def test_augmenting__sans_date(self): inv = inventory.Inventory() wash_calculator.book_position( inv, DD('2014-02-10'), position.from_string('10 HOOL {500 USD}')) wash_calculator.book_position(inv, DD('2014-02-10'), position.from_string('7 HOOL {500 USD}')) self.assertEqual( inventory.from_string('17 HOOL {500 USD / 2014-02-10}'), inv)
def test_segment_periods_no_constraint(self): # Test the default case, no beginning. timeline = returns.segment_periods(self.entries, self.assets, self.assets) self.assertEqual([ (datetime.date(2014, 1, 15), datetime.date(2014, 1, 15)), (datetime.date(2014, 1, 15), datetime.date(2014, 6, 15)), (datetime.date(2014, 6, 15), datetime.date(2014, 10, 1)), ], dates_from_timeline(timeline)) self.assertEqual(inventory.from_string(''), timeline[0].end.balance)
def test_aggregated_group_by_invisible_order_by_non_aggregate_visible(self): # GROUP-BY: 'account' is invisible. # ORDER-BY: 'len(account)' is a non-aggregate and visible. self.check_query( self.INPUT, """ SELECT length(account) as len, sum(position) as amount GROUP BY account, len ORDER BY len; """, [ ('len', int), ('amount', inventory.Inventory), ], [ (19, inventory.from_string('-100.00 USD'),), (20, inventory.from_string('100.00 USD'),), ])
def test_get_residual_postings(self): residual = inventory.from_string('0.001 USD, -0.00002 CAD') account_rounding = 'Equity:RoundingError' postings = interpolate.get_residual_postings(residual, account_rounding) self.assertEqual(2, len(postings)) self.assertEqual([ P(None, "Equity:RoundingError", "-0.001", "USD"), P(None, "Equity:RoundingError", "0.00002", "CAD"), ], [posting._replace(meta=None) for posting in postings])
def test_get_incomplete_postings_residual(self): meta = data.new_metadata(__file__, 0) # Test with a single auto-posting with a residual. entry = data.Transaction(meta, None, None, None, None, None, None, [ P(None, "Assets:Bank:Checking", "105.50", "USD"), P(None, "Assets:Bank:Savings", "-115.501", "USD"), P(None, "Assets:Bank:Balancing", "10.00", "USD"), ]) _, __, ___, residual, ____ = interpolate.get_incomplete_postings(entry, OPTIONS_MAP) self.assertEqual(inventory.from_string('-0.001 USD'), residual)
def test_precision(self): # Some display context. dcontext = display_context.DisplayContext() dcontext.update(D('111'), 'JPY') dcontext.update(D('1.111'), 'RGAGX') dcontext.update(D('1.11'), 'USD') dformat = dcontext.build() # Input data. itypes = [('number', Decimal), ('amount', amount.Amount), ('position', position.Position), ('inventory', inventory.Inventory)] irows = [[D(amt.split()[0]), A(amt), position.from_string(amt), inventory.from_string(amt)] for amt in ['123.45678909876 JPY', '1.67321232123 RGAGX', '5.67345434543 USD']] # First check with no explicit quantization. atypes, arows = numberify.numberify_results(itypes, irows) erows = [[D('123.45678909876'), None, None, D('123.45678909876'), None, None, D('123.45678909876'), None, None, D('123.45678909876')], [D('1.67321232123'), None, D('1.67321232123'), None, None, D('1.67321232123'), None, None, D('1.67321232123'), None], [D('5.67345434543'), D('5.67345434543'), None, None, D('5.67345434543'), None, None, D('5.67345434543'), None, None]] self.assertEqual(erows, arows) # Then compare with quantization. atypes, arows = numberify.numberify_results(itypes, irows, dformat) erows = [[D('123.45678909876'), None, None, D('123'), None, None, D('123'), None, None, D('123')], [D('1.67321232123'), None, D('1.673'), None, None, D('1.673'), None, None, D('1.673'), None], [D('5.67345434543'), D('5.67'), None, None, D('5.67'), None, None, D('5.67'), None, None]] self.assertEqual(erows, arows)
def test_functions(self): # Just a smoke test. formatter = html_formatter.HTMLFormatter( display_context.DEFAULT_DISPLAY_CONTEXT) formatter.render_account('Assets:US:Bank:Checking') formatter.render_inventory( inventory.from_string('10 CAD, 2 HOOL {500 USD}')) formatter.render_context('2b4722c3f89f43841cacf16325c2') formatter.render_link('fc6189c48a53') formatter.render_doc('/path/to/my/document.pdf') formatter.render_event_type('location') formatter.render_commodity(('HOOL', 'USD')) formatter.render_source( data.new_metadata('/path/to/my/input.beancount', 17))
def __test_flatten(self): self.check_query( self.INPUT, """ SELECT account, sum(position) WHERE account = 'Assets:Something' GROUP BY account FLATTEN; """, [ ('account', str), ('sum_position', inventory.Inventory), ], [ ('Assets:Something', inventory.from_string( "5.00 USD, 2.00 CAD, 4 HOOL {531.20 USD}")), ])
def test_from_string(self): inv = inventory.from_string('') self.assertEqual(Inventory(), inv) inv = inventory.from_string('10 USD') self.assertEqual( Inventory([Position(Lot("USD", None, None), D('10'))]), inv) inv = inventory.from_string(' 10.00 USD ') self.assertEqual( Inventory([Position(Lot("USD", None, None), D('10'))]), inv) inv = inventory.from_string('1 USD, 2 CAD') self.assertEqual( Inventory([Position(Lot("USD", None, None), D('1')), Position(Lot("CAD", None, None), D('2'))]), inv) inv = inventory.from_string('2.2 HOOL {532.43 USD}, 3.413 EUR') self.assertEqual( Inventory([Position(Lot("HOOL", A('532.43 USD'), None), D('2.2')), Position(Lot("EUR", None, None), D('3.413'))]), inv) inv = inventory.from_string( '2.2 HOOL {532.43 USD}, 2.3 HOOL {564.00 USD, 2015-07-14}, 3.413 EUR') self.assertEqual( Inventory([Position(Lot("HOOL", A('532.43 USD'), None), D('2.2')), Position(Lot("HOOL", A('564.00 USD'), datetime.date(2015, 7, 14)), D('2.3')), Position(Lot("EUR", None, None), D('3.413'))]), inv) inv = inventory.from_string( '1.1 HOOL {500.00 # 11.00 USD}, 100 CAD') self.assertEqual( Inventory([Position(Lot("HOOL", A('510.00 USD'), None), D('1.1')), Position(Lot("CAD", None, None), D('100'))]), inv)
def test_from_string(self): inv = inventory.from_string('') self.assertEqual(Inventory(), inv) inv = inventory.from_string('10 USD') self.assertEqual( Inventory([Position(A("10 USD"))]), inv) inv = inventory.from_string(' 10.00 USD ') self.assertEqual( Inventory([Position(A("10 USD"))]), inv) inv = inventory.from_string('1 USD, 2 CAD') self.assertEqual( Inventory([Position(A("1 USD")), Position(A("2 CAD"))]), inv) inv = inventory.from_string('2.2 HOOL {532.43 USD}, 3.413 EUR') self.assertEqual( Inventory([Position(A("2.2 HOOL"), Cost(D('532.43'), 'USD', None, None)), Position(A("3.413 EUR"))]), inv) inv = inventory.from_string( '2.2 HOOL {532.43 USD}, 2.3 HOOL {564.00 USD, 2015-07-14}, 3.413 EUR') self.assertEqual( Inventory([Position(A("2.2 HOOL"), Cost(D('532.43'), 'USD', None, None)), Position(A("2.3 HOOL"), Cost(D('564.00'), 'USD', datetime.date(2015, 7, 14), None)), Position(A("3.413 EUR"))]), inv) inv = inventory.from_string( '1.1 HOOL {500.00 # 11.00 USD}, 100 CAD') self.assertEqual( Inventory([Position(A("1.1 HOOL"), Cost(D('510.00'), 'USD', None, None)), Position(A("100 CAD"))]), inv)
def test_stock_many_lots(self): balances = inventory.from_string( '2 HOOL {0.01 USD}, 3 HOOL {0.02 USD}') market_value = prices.get_inventory_market_value( balances, datetime.date(2013, 6, 6), self.price_map) self.assertEqual(inventory.from_string('530 USD'), market_value)
def test_stock_different_ones(self): balances = inventory.from_string( '2 HOOL {0.01 USD}, 2 AAPL {0.02 USD}') market_value = prices.get_inventory_market_value( balances, datetime.date(2013, 6, 6), self.price_map) self.assertEqual(inventory.from_string('404 USD'), market_value)
def test_stock_not_found(self): balances = inventory.from_string('2 MSFT {0.01 USD}') market_value = prices.get_inventory_market_value( balances, datetime.date(2013, 6, 6), self.price_map) self.assertEqual(inventory.from_string('2 MSFT {0.01 USD}'), market_value)
def create_real(account_value_pairs): real_root = RealAccount('') for account_name, value in account_value_pairs: real_account = realization.get_or_create(real_root, account_name) real_account.balance += inventory.from_string(value) return real_root
def setUp(self): self.balances = collections.defaultdict(inventory.Inventory) self.balances['Assets:US:Investment'] = ( inventory.from_string('10 HOOL {500.00 USD}')) self.balances['Assets:US:Bank:Checking'] = inventory.from_string( '1823.23 USD')
def test_from_string(self): inv = inventory.from_string('') self.assertEqual(Inventory(), inv)