budget/tests/test_transform.py
Luís Murta 01df97ed46
back_populates option on category relationship
Due to the use of the dataclasses mixin on the SQLAlchemy types, a
back_populates creates a RecursiveError when comparing two types. This
occurs because the dataclass will overwrite the __eq__ operator, and it
doesn't know when to stop comparing relationships.

Removing the dataclasses isn't the best approach, since then __init__,
__eq__ and __repr__ methods would have to be added to all types. Thus
the solution was to remove the relationship on the child (on a
one-to-one relationship) from the __eq__ operation, with the use of the
compare parameter.

Took the opportunity to define more logical __init__ methods on the
`Rule` and child classes.
Also revised the parameter options on some DB types.
2024-01-22 21:45:49 +00:00

110 lines
3.3 KiB
Python

from datetime import date
from decimal import Decimal
import mocks.categories as mock
from pfbudget.db.model import (
BankTransaction,
CategoryRule,
CategorySelector,
Selector_T,
TransactionCategory,
TransactionTag,
)
from pfbudget.transform.categorizer import Categorizer
from pfbudget.transform.nullifier import Nullifier
from pfbudget.transform.tagger import Tagger
from pfbudget.transform.transform import Transformer
class TestTransform:
def test_nullifier(self):
transactions = [
BankTransaction(date(2023, 1, 1), "", Decimal("-500"), bank="Bank#1"),
BankTransaction(date(2023, 1, 2), "", Decimal("500"), bank="Bank#2"),
]
for t in transactions:
assert not t.category
categorizer: Transformer = Nullifier()
transactions = categorizer.transform(transactions)
for t in transactions:
assert t.category == TransactionCategory(
"null", CategorySelector(Selector_T.nullifier)
)
def test_nullifier_inplace(self):
transactions = [
BankTransaction(date(2023, 1, 1), "", Decimal("-500"), bank="Bank#1"),
BankTransaction(date(2023, 1, 2), "", Decimal("500"), bank="Bank#2"),
]
for t in transactions:
assert not t.category
categorizer: Transformer = Nullifier()
categorizer.transform_inplace(transactions)
for t in transactions:
assert t.category == TransactionCategory(
"null", CategorySelector(Selector_T.nullifier)
)
def test_nullifier_with_rules(self):
transactions = [
BankTransaction(date(2023, 1, 1), "", Decimal("-500"), bank="Bank#1"),
BankTransaction(date(2023, 1, 2), "", Decimal("500"), bank="Bank#2"),
]
for t in transactions:
assert not t.category
rules = [CategoryRule("null", bank="Bank#1")]
categorizer: Transformer = Nullifier(rules)
transactions = categorizer.transform(transactions)
for t in transactions:
assert not t.category
rules.append(CategoryRule("null", bank="Bank#2"))
categorizer = Nullifier(rules)
transactions = categorizer.transform(transactions)
for t in transactions:
assert t.category == TransactionCategory(
"null", CategorySelector(Selector_T.nullifier)
)
def test_tagger(self):
transactions = [
BankTransaction(date(2023, 1, 1), "desc#1", Decimal("-10"), bank="Bank#1")
]
for t in transactions:
assert not t.category
categorizer: Transformer = Tagger(mock.tag_1.rules)
transactions = categorizer.transform(transactions)
for t in transactions:
assert TransactionTag("tag#1") in t.tags
def test_categorize(self):
transactions = [
BankTransaction(date(2023, 1, 1), "desc#1", Decimal("-10"), bank="Bank#1")
]
for t in transactions:
assert not t.category
categorizer: Transformer = Categorizer(mock.category1.rules)
transactions = categorizer.transform(transactions)
for t in transactions:
assert t.category == TransactionCategory(
"cat#1", CategorySelector(Selector_T.rules)
)