Files
jze9 b2d2061a83 refactor(indexer): вынести разбиение на фрагменты в app.fragments + 5 тестов
_split_into_fragments жила в тяжёлой Celery-задаче (celery/sqlalchemy/minio) и
не тестировалась, хотя именно она определяет, ЧТО проверяется на плагиат.
Вынес в чистый app.fragments.split_into_fragments — тестируется изолированно:

- пустой/пробельный текст → [];
- текст короче 20 слов → отбрасывается порогом длины;
- короткий текст → один фрагмент на весь объём, start=0;
- скользящее окно: перекрытие ровно (window-step) слов, хвост==голова соседа;
- start/end — корректные символьные офсеты в исходный текст.

Поведение сохранено 1:1. Добавлен в mypy-гейт. Тестов всего: 66.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-11 20:17:33 +05:00

44 lines
1.8 KiB
Python
Raw Permalink 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.
"""Юнит-тесты разбиения текста на фрагменты (определяет, что проверяется)."""
from app.fragments import split_into_fragments
def _text(n: int) -> str:
"""n слов одинаковой длины: 'w000 w001 ... ' (по 4 символа + пробел)."""
return " ".join(f"w{i:03d}" for i in range(n))
def test_empty_text_returns_empty():
assert split_into_fragments("") == []
assert split_into_fragments(" ") == []
def test_text_shorter_than_min_words_is_dropped():
# < 20 слов → единственный кандидат отбрасывается порогом длины
assert split_into_fragments(_text(19), window=200, overlap=50) == []
def test_short_text_single_fragment_covers_all():
frags = split_into_fragments(_text(30), window=200, overlap=50)
assert len(frags) == 1
assert frags[0]["start"] == 0
assert frags[0]["text"] == _text(30)
def test_sliding_window_overlap():
frags = split_into_fragments(_text(50), window=25, overlap=5)
# step = window - overlap = 20 → окна начинаются со слов 0 и 20
assert len(frags) == 2
words0 = frags[0]["text"].split()
words1 = frags[1]["text"].split()
assert len(words0) == 25 and len(words1) == 25
# перекрытие ровно 5 слов: хвост первого == голова второго
assert words0[-5:] == words1[:5]
def test_char_positions_are_offsets_into_source_text():
text = _text(30)
f = split_into_fragments(text, window=25, overlap=5)[0]
assert text[f["start"]:].startswith("w000") # start — символьный офсет начала
assert text[: f["end"]].endswith("w024") # end — конец 25-го слова окна