Этап: SQLite и запуск пайплайна

This commit is contained in:
vladslav064 committed 2026-11-12 08:43:34 +03:00
1 parent 626ac21b41
commit d90f1f30b2
15 files changed
+2069 -6

No files matched your search

+60
View File
@@ -1,4 +1,5 @@
import csv
from pathlib import Path
import pytest
@@ -116,3 +117,62 @@ def test_missing_or_damaged_file(tmp_path):
path.write_text(",".join(FIELDS) + '\n1,2024-02-29,"незакрытое поле', encoding="utf-8")
with pytest.raises(CSVFileError, match="ошибка структуры CSV"):
clean_orders(read_records(path))
def test_invalid_utf8(tmp_path):
path = tmp_path / "orders.csv"
path.write_bytes(",".join(FIELDS).encode() + b"\n1,2024-01-01,\xff,1,1\n")
with pytest.raises(CSVFileError, match="UTF-8") as error:
list(read_records(path))
assert str(path) in str(error.value)
def test_access_denied(tmp_path, monkeypatch):
path = tmp_path / "private.csv"
def deny_access(self, *args, **kwargs):
raise PermissionError("access denied")
monkeypatch.setattr(Path, "open", deny_access)
with pytest.raises(CSVFileError, match="ошибка чтения") as error:
list(read_records(path))
assert str(path) in str(error.value)
assert isinstance(error.value.__cause__, PermissionError)
def test_logical_record_numbers_across_multiline_field(tmp_path):
path = tmp_path / "orders.csv"
path.write_bytes((",".join(FIELDS) + '\r\n1,2024-02-29,"дом,\r\nсад",1,10\r\n'
'\r\n2,2024-03-01,книги,2,3\r\n').encode())
records = list(read_records(path))
assert [r.record_number for r in records] == [1, 2, 3]
assert records[0].values[2] == "дом,\r\nсад"
assert records[1].structure_error == "Пустая запись CSV"
assert records[2].values[0] == "2"
def test_order_and_reasons_across_processing_stages(tmp_path):
conflict = order(order_id="9")
bad = order(quantity="-1", unit_price="0.001")
accepted, rejected = process(
tmp_path, conflict, order(order_id="8"), bad, conflict,
conflict | {"order_date": "29.02.2024"}, order(), bad,
conflict | {"quantity": "2"}, order(order_id="08"),
)
assert [(o.record_number, o.order_id) for o in accepted] == [(2, 8), (6, 1)]
assert [(r.source.record_number, r.reasons) for r in rejected] == [
(1, ["Конфликт order_id"]),
(3, ["quantity: ожидается положительное целое число", "unit_price: больше двух дробных знаков"]),
(4, ["Точный дубль"]),
(5, ["Конфликт order_id"]),
(7, ["Точный дубль"]),
(8, ["Конфликт order_id"]),
(9, ["Нормализованный дубль"]),
]
def test_large_price_preserves_last_kopeck(tmp_path):
accepted, rejected = process(tmp_path, order(unit_price="90071992547409,93", quantity="3"))
assert not rejected
assert accepted[0].unit_price_kopecks == 9_007_199_254_740_993
assert accepted[0].revenue_kopecks == 27_021_597_764_222_979