Adds remaining files from parallel development: - Services: analysis, csv_reader, forecasting, normalizer, recurring - UI: recurring_view, settings_view, sidebar, themes (dark/light) - Tests: analysis, csv_reader, forecasting, import_categorize, normalizer, recurring, integration - App entry point (main.py) and CLAUDE.md 52 tests passing across all modules. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
43 lines
1.3 KiB
Python
43 lines
1.3 KiB
Python
from pathlib import Path
|
|
from src.services.csv_reader import read_csv, detect_format
|
|
|
|
RAWDATA = Path(__file__).parent.parent.parent / "rawdata"
|
|
|
|
|
|
def test_detect_chase_format():
|
|
result = detect_format(RAWDATA / "Chase0372_Activity20260101_20260210_20260210.CSV")
|
|
assert result["has_headers"] is True
|
|
assert "Transaction Date" in result["headers"]
|
|
assert result["delimiter"] == ","
|
|
assert result["row_count"] > 0
|
|
|
|
|
|
def test_detect_checking_format():
|
|
result = detect_format(RAWDATA / "Checking1.csv")
|
|
assert result["has_headers"] is False
|
|
assert result["column_count"] == 5
|
|
assert result["row_count"] > 0
|
|
|
|
|
|
def test_read_chase_csv():
|
|
rows = read_csv(RAWDATA / "Chase0372_Activity20260101_20260210_20260210.CSV")
|
|
assert len(rows) > 100
|
|
first = rows[0]
|
|
assert "Transaction Date" in first
|
|
assert "Amount" in first
|
|
assert "Description" in first
|
|
|
|
|
|
def test_read_headerless_csv():
|
|
rows = read_csv(RAWDATA / "Checking1.csv")
|
|
assert len(rows) > 50
|
|
first = rows[0]
|
|
# Headerless: keys should be column indices (integers)
|
|
assert 0 in first or "0" in first
|
|
|
|
|
|
def test_preview_rows():
|
|
result = detect_format(RAWDATA / "Chase0372_Activity20260101_20260210_20260210.CSV")
|
|
assert "preview" in result
|
|
assert len(result["preview"]) <= 5
|