import pytest from app.domain import TransactionKind from app.parser import ParseError, format_money, parse_money_amount, parse_transaction @pytest.mark.parametrize( ("text", "kopecks", "description", "kind"), [ ("467 ярче", 46_700, "ярче", TransactionKind.EXPENSE), ("3 000 бензин", 300_000, "бензин", TransactionKind.EXPENSE), ("199,90 кофе", 19_990, "кофе", TransactionKind.EXPENSE), ("+ 85 000 зарплата", 8_500_000, "зарплата", TransactionKind.INCOME), ("доход 5000 подработка", 500_000, "подработка", TransactionKind.INCOME), ("расход 1200 кино", 120_000, "кино", TransactionKind.EXPENSE), ], ) def test_parse_transaction(text, kopecks, description, kind): parsed = parse_transaction(text) assert parsed.amount_kopecks == kopecks assert parsed.description == description assert parsed.kind is kind @pytest.mark.parametrize("text", ["просто текст", "0 кофе", "500", "- доход 500 премия"]) def test_rejects_invalid_input(text): with pytest.raises(ParseError): parse_transaction(text) def test_format_money(): assert format_money(123_456_00) == "123 456 ₽" assert format_money(-199_90, signed=True) == "−199,90 ₽" @pytest.mark.parametrize( ("text", "kopecks"), [("530713", 53_071_300), ("530 713 ₽", 53_071_300), ("1250,50 руб", 125_050)], ) def test_parse_money_amount(text, kopecks): assert parse_money_amount(text) == kopecks @pytest.mark.parametrize( ("text", "kopecks", "description", "kind", "debt_effect"), [ ("-5000 ЗП", 500_000, "ЗП", TransactionKind.INCOME, -1), ("-5000 зарплата", 500_000, "зарплата", TransactionKind.INCOME, -1), ("-5000 рабочий закуп", 500_000, "рабочий закуп", TransactionKind.EXPENSE, -1), ("-3000 бензин", 300_000, "бензин", TransactionKind.EXPENSE, -1), ("3000 бензин", 300_000, "бензин", TransactionKind.EXPENSE, 1), ("+3000 бензин", 300_000, "бензин", TransactionKind.EXPENSE, 1), ("+ 5000 зарплата", 500_000, "зарплата", TransactionKind.INCOME, -1), ("5000 зарплата", 500_000, "зарплата", TransactionKind.INCOME, -1), ("доход 5000 подработка", 500_000, "подработка", TransactionKind.INCOME, -1), ], ) def test_parse_transaction_debt_effect(text, kopecks, description, kind, debt_effect): parsed = parse_transaction(text) assert parsed.amount_kopecks == kopecks assert parsed.description == description assert parsed.kind is kind assert parsed.debt_effect == debt_effect @pytest.mark.parametrize( ("text", "kind"), [ ("5000 ЗП", TransactionKind.INCOME), ("5000 зарплата", TransactionKind.INCOME), ("+ ЗП 5000", TransactionKind.INCOME), ("расход 5000 зарплата", TransactionKind.INCOME), ], ) def test_salary_recognised_as_income(text, kind): parsed = parse_transaction(text) assert parsed.kind is kind @pytest.mark.parametrize("text", ["- доход 500 премия", "- приход 1000 подработка"]) def test_rejects_negative_income_conflict(text): with pytest.raises(ParseError, match="Доход не может быть отрицательным"): parse_transaction(text) def test_amount_kopecks_always_positive(): parsed = parse_transaction("-5000 ЗП") assert parsed.amount_kopecks > 0 assert parsed.amount_kopecks == 500_000