Files
memo/e2e/mutations.tsv
T
subochev 69a0ebe0fa tests: ModelStoreTest — закрыты дыры покрытия Range и Content-Range
resumesPartialDownload: счётчики Range-запросов и байт; сервер отдаёт 400
без Range для .part — запасной путь «начать заново» закрыт.

failsOnSizeMismatch разделена на два:
  - rejectsWrongTotalFromContentRange — сервер соврал в Content-Range,
    бьёт в проверку actualTotal != expectedTotal (вторая, достижимая);
  - truncatedResponseDoesNotProduceFile — оборванный ответ, по факту ловит
    ветку IOException → «не удалось скачать» (а не first size check).

В mutations.tsv убрана строка про if (declaredBody >= 0 && written !=
declaredBody) — через java.net/http недостижимо (оборванный ответ даёт
IOException, не EOF). Добавлена строка про if (expectedTotal >= 0 &&
actualTotal != expectedTotal) — теперь убивает rejectsWrongTotalFromContentRange.

Все 18 мутаций (4 из ModelStore) убиты прогоном mutation_check.py.
2026-10-02 04:48:35 +03:00

3.5 KiB

1# file<TAB>old<TAB>new<TAB>must_fail_test
2# Прогон: python3 e2e/mutation_check.py --gradle ./gradlew
3# Правило: мутация обязана уронить ровно тот тест, который её ловит. Выжившая мутация = дыра в покрытии.
4# no-op мутации (old == new) запрещены — харнесс их отклоняет.
5# --- memo-core: ksqlite / FTS5 / vec0 ---
6memo-core/src/test/kotlin/memo/core/CoreSmokeTest.ktCREATE VIRTUAL TABLE v USING vec0(embedding float[4])CREATE VIRTUAL TABLE v USING vec0(embedding float[8])vec0KnnRoundTrip
7memo-core/src/test/kotlin/memo/core/CoreSmokeTest.ktfloatArrayOf(0.1f, 0.9f, 0.0f, 0.0f)floatArrayOf(0.0f, 0.0f, 0.0f, 1.0f)vec0KnnRoundTrip
8memo-core/src/test/kotlin/memo/core/CoreSmokeTest.kttokenize='unicode61'tokenize='ascii'fts5FindsCyrillic
9memo-core/src/test/kotlin/memo/core/CoreSmokeTest.ktSELECT a FROM tSELECT a+1 FROM tksqliteSmoke
10# --- Чанкер ---
11memo-core/src/main/kotlin/memo/core/Chunker.ktval trimmed = body.trim()val trimmed = body.uppercase()fourHashesIsNotAHeading
12memo-core/src/main/kotlin/memo/core/Chunker.ktprivate const val CHUNK_OVERLAP = 600private const val CHUNK_OVERLAP = 0longSectionIsSplitWithOverlap
13# --- Коллекции (дефект тройного обхода, найден на приёмке) ---
14# --- Индексатор: пропуск неизменённого файла ---
15memo-core/src/main/kotlin/memo/core/Indexer.ktif (existing.mtime == mtime && existing.size == size) {\n return falseif (existing.mtime == mtime && existing.size == size) {\n return trueindexerSkipsUnchangedFile
16# --- Поиск: слияние режимов и ограничение k ---
17memo-core/src/main/kotlin/memo/core/Searcher.ktif (mode == SearchMode.LEX || mode == SearchMode.HYBRID) lexSearch(query) else emptyList()if (mode == SearchMode.LEX) lexSearch(query) else emptyList()hybridCombinesBoth
18memo-core/src/main/kotlin/memo/core/Searcher.kt.sortedByDescending { it.value }.take(k).sortedByDescending { it.value }.take(k + 1)resultsRespectKAndTextLength
19# --- MCP: ошибка инструмента обязана помечаться isError ---
20# --- Watcher: debounce сводит правки к одному вызову ---
21memo-watch/src/main/kotlin/memo/watch/Watcher.kt_indexCalls.incrementAndGet()_indexCalls.get()modifyTriggersSingleIndexCall
22# --- ModelStore: скачивание модели (ModelStoreTest) ---
23memo-core/src/main/kotlin/memo/core/ModelStore.ktif (!force && target.isFile && target.length() > 0L) {if (false) {skipsExistingWithoutNetwork
24memo-core/src/main/kotlin/memo/core/ModelStore.ktif (expectedTotal >= 0 && actualTotal != expectedTotal) {if (false) {rejectsWrongTotalFromContentRange