Oracle / tests /test_categories.py
spacedout-bits's picture
Deploy coco-finbot
bfd6783 verified
Raw History Blame Contribute Delete
3.02 kB
import pytest
from finbot.categories import CATEGORIES, categorise, coerce, is_valid, label
class TestCategorise:
@pytest.mark.parametrize(
"text,expected",
[
("uber ride home", "transport"),
("netflix monthly", "subscriptions"),
("bigbasket order", "groceries"),
("swiggy dinner", "food_dining"),
("petrol pump", "fuel"),
("electricity bill", "utilities"),
("apollo pharmacy", "health"),
("bookmyshow tickets", "entertainment"),
("amazon order", "shopping"),
("atm withdrawal", "cash"),
("salary credited", "income"),
],
)
def test_keyword_hits(self, text, expected):
category, confidence = categorise(text)
assert category == expected
assert confidence == 1.0
def test_unknown_returns_other_with_zero_confidence(self):
category, confidence = categorise("blorptastic widget")
assert category == "other"
assert confidence == 0.0
def test_empty_input(self):
assert categorise("") == ("other", 0.0)
def test_specificity_order_fuel_beats_transport(self):
# A petrol pump is fuel, even though it is transport-adjacent.
assert categorise("indian oil petrol")[0] == "fuel"
def test_specificity_order_subscription_beats_entertainment(self):
assert categorise("netflix")[0] == "subscriptions"
def test_word_boundaries_prevent_false_hits(self):
# "cashew" must not match the "cash" keyword.
assert categorise("cashew nuts")[0] != "cash"
# "gasket" must not match "gas station".
assert categorise("engine gasket")[0] != "fuel"
def test_merchant_is_considered(self):
category, _ = categorise("monthly charge", merchant="Spotify")
assert category == "subscriptions"
def test_case_insensitive(self):
assert categorise("UBER RIDE")[0] == "transport"
class TestCoerce:
@pytest.mark.parametrize(
"raw,expected",
[
("food_dining", "food_dining"),
("Food", "food_dining"),
("dining", "food_dining"),
("grocery", "groceries"),
("healthcare", "health"),
("Subscription", "subscriptions"),
("misc", "other"),
("", "other"),
("total nonsense", "other"),
],
)
def test_coerce(self, raw, expected):
assert coerce(raw) == expected
def test_every_result_is_a_valid_category(self):
# A stray label from a model must never reach the ledger, or totals
# fragment across categories that do not exist.
for raw in ["", "???", "Investments", "food", "TRANSPORT", "x" * 200]:
assert is_valid(coerce(raw))
class TestLabels:
def test_every_category_has_a_label(self):
for category in CATEGORIES:
assert label(category)
assert label(category) != category or "_" not in category