Files
drhider/tests/test_builder.py
T

134 lines
6.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Тесты builder.py — создание ZIP и mapping.csv.
Запуск: python3 tests/test_builder.py
"""
import io
import zipfile
import sys
import os
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from drhider.builder import build_zip, build_mapping_csv
passed = 0
failed = 0
def check(name, condition):
global passed, failed
if condition:
passed += 1
print(f" ✅ {name}")
else:
failed += 1
print(f" ❌ {name}")
# ═══════════════════════════════════════════════════════════════
# Test build_zip
# ═══════════════════════════════════════════════════════════════
print("\n=== build_zip ===")
# 1. Базовый ZIP с одним файлом
zip_data = build_zip([("test.md", b"content")])
with zipfile.ZipFile(io.BytesIO(zip_data)) as zf:
names = zf.namelist()
check("один файл в ZIP", len(names) == 1)
check("имя test.md", "test.md" in names)
check("контент верный", zf.read("test.md") == b"content")
# 2. ZIP с несколькими файлами
zip_data = build_zip([
("договор_obfuscated.md", "# Договор\nТекст".encode("utf-8")),
("спецификация_obfuscated.md", "| Услуга | Цена |".encode("utf-8")),
])
with zipfile.ZipFile(io.BytesIO(zip_data)) as zf:
names = zf.namelist()
check("два файла", len(names) == 2)
check("mapping.csv нет", "mapping.csv" not in names)
check("договор читается", "Договор" in zf.read("договор_obfuscated.md").decode("utf-8"))
# 3. ZIP с mapping.csv
zip_data = build_zip(
[("file.md", b"data")],
mapping_csv="тип,оригинал,замена\nperson,Иванов,Иванов_0001\n"
)
with zipfile.ZipFile(io.BytesIO(zip_data)) as zf:
names = zf.namelist()
check("mapping.csv есть", "mapping.csv" in names)
csv_content = zf.read("mapping.csv").decode("utf-8")
check("mapping с BOM", csv_content.startswith('\ufeff'))
check("данные в mapping", "Иванов_0001" in csv_content)
# 4. ZIP с кириллицей в именах
zip_data = build_zip([("договор_№123.md", "текст".encode("utf-8"))])
with zipfile.ZipFile(io.BytesIO(zip_data)) as zf:
check("кириллическое имя читается", "договор_№123.md" in zf.namelist())
# 5. ZIP с бинарными данными
binary = bytes(range(256))
zip_data = build_zip([("binary.bin", binary)])
with zipfile.ZipFile(io.BytesIO(zip_data)) as zf:
check("бинарный файл сохранён", zf.read("binary.bin") == binary)
# 6. Пустой mapping
zip_data = build_zip([("f.md", b"x")], mapping_csv="")
with zipfile.ZipFile(io.BytesIO(zip_data)) as zf:
check("пустой mapping не добавляется", "mapping.csv" not in zf.namelist())
# ═══════════════════════════════════════════════════════════════
# Test build_mapping_csv
# ═══════════════════════════════════════════════════════════════
print("\n=== build_mapping_csv ===")
# 1. Простой mapping
mapping = {"Иванов И.И.": "Иванов_0001"}
csv_str = build_mapping_csv(mapping)
check("заголовок есть", csv_str.startswith("тип_данных,оригинал,замена"))
check("данные есть", "Иванов_0001" in csv_str)
# 2. Пустой mapping
csv_str = build_mapping_csv({})
lines = csv_str.strip().split("\n")
check("пустой — только заголовок", len(lines) == 1)
# 3. Сортировка
mapping = {"Б": "Б_0001", "А": "А_0001"}
csv_str = build_mapping_csv(mapping)
check("сортировка А перед Б", csv_str.index("А_0001") < csv_str.index("Б_0001"))
# 4. Кавычки в значениях
mapping = {'ООО "Ромашка"': "ООО_Технология_0001"}
csv_str = build_mapping_csv(mapping)
check("кавычки экранированы", 'ООО "Ромашка"' in csv_str or 'ООО ""Ромашка""' in csv_str)
# ═══════════════════════════════════════════════════════════════
# Test: интеграция build_zip + build_mapping_csv
# ═══════════════════════════════════════════════════════════════
print("\n=== build_zip + build_mapping_csv ===")
mapping = {"Иванов И.И.": "Иванов_0001", "ООО Ромашка": "ООО_Технология_0001"}
csv = build_mapping_csv(mapping)
zip_data = build_zip([("doc.md", "# Договор с Иванов_0001".encode("utf-8"))], mapping_csv=csv)
with zipfile.ZipFile(io.BytesIO(zip_data)) as zf:
check("два файла в ZIP", len(zf.namelist()) == 2)
doc = zf.read("doc.md").decode("utf-8")
check("doc с заменой", "Иванов_0001" in doc)
csv_content = zf.read("mapping.csv").decode("utf-8")
check("CSV с обеими заменами", "Иванов_0001" in csv_content and "ООО_Технология_0001" in csv_content)
# ═══════════════════════════════════════════════════════════════
print(f"\n{'='*50}")
print(f"Результат: {passed} OK, {failed} FAIL из {passed + failed}")
if failed > 0:
print("❌ ТЕСТЫ ПРОВАЛЕНЫ")
sys.exit(1)
else:
print("✅ ВСЕ ТЕСТЫ ПРОЙДЕНЫ")