Changeset - fff9e37bf83e
[Not reviewed]
0 3 0
Brett Smith - 4 years ago 2020-07-16 14:11:39
brettcsmith@brettcsmith.org
data: Add Account.is_account and Account.load_options_map.

These work in concert to distinguish account names from other
colon-separated strings.
3 files changed with 67 insertions and 0 deletions:
0 comments (0 inline, 0 general)
conservancy_beancount/data.py
Show inline comments
...
 
@@ -32,2 +32,3 @@ from beancount.core import data as bc_data
 
from beancount.core import position as bc_position
 
from beancount.parser import options as bc_options
 

	
...
 
@@ -42,2 +43,3 @@ from typing import (
 
    Optional,
 
    Pattern,
 
    Sequence,
...
 
@@ -55,2 +57,3 @@ from .beancount_types import (
 
    Open,
 
    OptionsMap,
 
    Posting as BasePosting,
...
 
@@ -155,4 +158,15 @@ class Account(str):
 

	
 
    ACCOUNT_RE: Pattern
 
    SEP = bc_account.sep
 
    _meta_map: MutableMapping[str, AccountMeta] = {}
 
    _options_map: OptionsMap
 

	
 
    @classmethod
 
    def load_options_map(cls, options_map: OptionsMap) -> None:
 
        cls._options_map = options_map
 
        roots: Sequence[str] = bc_options.get_account_types(options_map)
 
        cls.ACCOUNT_RE = re.compile(
 
            r'^(?:{})(?:{}[A-Z0-9][-A-Za-z0-9]*)+$'.format(
 
                '|'.join(roots), cls.SEP,
 
            ))
 

	
...
 
@@ -180,2 +194,6 @@ class Account(str):
 

	
 
    @classmethod
 
    def is_account(cls, s: str) -> bool:
 
        return cls.ACCOUNT_RE.fullmatch(s) is not None
 

	
 
    @property
...
 
@@ -288,2 +306,3 @@ class Account(str):
 
            return self[:stop]
 
Account.load_options_map(bc_options.OPTIONS_DEFAULTS)
 

	
tests/test_data_account.py
Show inline comments
...
 
@@ -23,2 +23,3 @@ from datetime import date as Date
 
from beancount.core.data import Open, Close, Booking
 
from beancount.parser import options as bc_options
 

	
...
 
@@ -269 +270,46 @@ def test_load_openings_and_closings(clean_account_meta):
 
    check_account_meta('Assets:Checking', entries[2], entries[-1])
 

	
 
@pytest.mark.parametrize('account_s', [
 
    'Assets:Bank:Checking',
 
    'Equity:Funds:Restricted',
 
    'Expenses:Other',
 
    'Income:Donations',
 
    'Liabilities:CreditCard:Visa',
 
])
 
def test_is_account(account_s):
 
    assert data.Account.is_account(account_s)
 

	
 
@pytest.mark.parametrize('account_s', [
 
    'Assets:Bank:12-345',
 
    'Equity:Funds:Restricted',
 
    'Expenses:Other',
 
    'Income:Donations',
 
    'Liabilities:CreditCard:Visa0123',
 
])
 
def test_is_account(clean_account_meta, account_s):
 
    assert data.Account.is_account(account_s)
 

	
 
@pytest.mark.parametrize('account_s', [
 
    'Assets:checking',
 
    'Assets::Cash',
 
    'Equity',
 
    'Liabilities:Credit Card',
 
    'income:Donations',
 
    'Expenses:Banking_Fees',
 
    'Revenue:Grants',
 
])
 
def test_is_not_account(clean_account_meta, account_s):
 
    assert not data.Account.is_account(account_s)
 

	
 
@pytest.mark.parametrize('account_s,expected', [
 
    ('Revenue:Donations', True),
 
    ('Costs:Other', True),
 
    ('Income:Donations', False),
 
    ('Expenses:Other', False),
 
])
 
def test_is_account_respects_configured_roots(clean_account_meta, account_s, expected):
 
    config = bc_options.OPTIONS_DEFAULTS.copy()
 
    config['name_expenses'] = 'Costs'
 
    config['name_income'] = 'Revenue'
 
    data.Account.load_options_map(config)
 
    assert data.Account.is_account(account_s) == expected
tests/testutil.py
Show inline comments
...
 
@@ -23,2 +23,3 @@ import beancount.core.data as bc_data
 
import beancount.loader as bc_loader
 
import beancount.parser.options as bc_options
 

	
...
 
@@ -45,2 +46,3 @@ TESTS_DIR = Path(__file__).parent
 
def clean_account_meta():
 
    data.Account.load_options_map(bc_options.OPTIONS_DEFAULTS)
 
    data.Account._meta_map.clear()
0 comments (0 inline, 0 general)