Подключить NSubstitute и мигрировать FakePasswordHasher, зафиксировать правила тестов
ci / build-test (push) Has been cancelled
ci / build-test (push) Has been cancelled
NSubstitute 6.1.0 в 5 тест-проектов; эталон миграции: FakePasswordHasher удалён, вместо него Support/TestHashers.New() (Substitute.For с детерминированной семантикой fake-hash:, DI-регистрации переведены на инстанс хелпера). Правила владельца в §11 код-стайла: классы напрямую не вызываем (DTO/хелперы/ экстеншены — исключения), моки через NSubstitute, маркерные классы не используем. План миграции оставшихся фейков — backlog TD-TESTS-NSUBSTITUTE. Build 5 sln 0/0, тесты 1340/130/52/38/9 зелёные.
This commit is contained in:
@@ -232,11 +232,16 @@
|
||||
- **Не дублировать `<summary>` интерфейса в реализации.** Если член объявлен в интерфейсе с XML-doc,
|
||||
в классе-реализации достаточно `/// <inheritdoc/>` (или вообще ничего, если doc наследуется настройкой).
|
||||
Текст описания пишется **один раз** — у интерфейса.
|
||||
- **Явная реализация интерфейсов — где возможно.** Предпочитать явную реализацию
|
||||
(`Task ICardStore.GetAsync(...)`), если член не является публичным API класса сам по себе. Если тип
|
||||
реализует член как собственный публичный сервис (нужен в DI/прямых вызовах) — допустима implicit,
|
||||
но решение осознанное.
|
||||
- **Явная реализация интерфейсов — по умолчанию** (`Task ICardStore.GetAsync(...)`). **[изм. 2026-09-11,
|
||||
решение владельца]** Классы напрямую не вызываются — только через интерфейсы; исключения: DTO/модели
|
||||
(напр. `Card` и семейство `I*Card`), хелперы, extension-классы. Весь прод-код уже переведён на явные
|
||||
реализации (codemod `scripts/make_explicit.py`, идемпотентный).
|
||||
- Один публичный тип интерфейса = один файл (как и для классов); имя файла = имя типа.
|
||||
- **Маркерные классы не используются** — если нужен маркер, это маркерный интерфейс
|
||||
(`IKanbanModule`, `ISharedKernel` и т.п.). **[изм. 2026-09-11]**
|
||||
- **Тесты: моки — через NSubstitute** (`Substitute.For<IPasswordHasher>()`), тестовые переменные
|
||||
типизируются интерфейсом. Новые hand-written фейк-классы не заводить; существующие мигрируются
|
||||
поэтапно (план — `backlog.md`, `TD-TESTS-NSUBSTITUTE`). **[изм. 2026-09-11]**
|
||||
|
||||
## 12. Приложение: сводная таблица правил именования
|
||||
|
||||
|
||||
@@ -34,9 +34,11 @@
|
||||
(запрет только для встроенных типов — как в §4); режимы «очевидный тип» и «прочие» оставлены `silent`
|
||||
осознанно: правка субъективна и потребовала бы ~1600 механических замен. Остаток встроенных типов
|
||||
выправлен `dotnet format style --diagnostics IDE0008` по всем 5 решениям (51 файл); сборка 5 sln — 0/0.
|
||||
2. **Явная реализация интерфейсов (§11) — остаётся точечным ревью владельца.** Замер: 54 интерфейса с XML-doc,
|
||||
из них 43 имеют реализации в src (в основном store-порты с одной реализацией). Массовая правка не
|
||||
автоматизируется сознательно (см. рекомендацию выше).
|
||||
2. **Явная реализация интерфейсов (§11) — выполнено (вечер, решение владельца, вариант A).** 161 член
|
||||
в 30 прод-файлах конвертирован codemod'ом `scripts/make_explicit.py` (частичные классы и многострочные
|
||||
сигнатуры учтены); потребители конкретных типов перетипизированы на интерфейсы (8 мест в проде,
|
||||
17 тест-файлов); `Card`/семейство `I*Card` оставлены implicit — это DTO, их члены и есть публичный API.
|
||||
Правило закреплено в §11 код-стайла: классы напрямую не вызываем (DTO/хелперы/экстеншены — исключения).
|
||||
3. **Дедупликация `<summary>` через `<inheritdoc/>` — закрыто: дублей нет.** Проверено двумя независимыми
|
||||
сканами (сопоставление по тексту и по имени члена интерфейса: 39 интерфейсов, 229 задокументированных
|
||||
членов) — реализаций, дублирующих summary интерфейсного члена, в продакшн-коде нет; случаев
|
||||
|
||||
@@ -31,6 +31,16 @@
|
||||
> остались точечным ревью владельца (43 интерфейса с реализациями, массовая правка не автоматизируется).
|
||||
> Сборка 5 sln 0/0; тесты: core **1340/1340**, telegram **130/130**, ai **52/52**, ml **38/38**, storage **9/9** — зелёные.
|
||||
> Детали — `docs/spec/Код-стайл-аудит-2026-09-11.md`, §2.
|
||||
>
|
||||
> **2026-09-11 (поздний вечер) — явные реализации интерфейсов (вариант A, решение владельца).** Правило
|
||||
> владельца: классы напрямую не вызываем (исключения — DTO, хелперы, экстеншены), тесты — через
|
||||
> интерфейсы, моки — NSubstitute, маркерные классы не используем. Сделано: 161 член в 30 прод-файлах
|
||||
> переведён на явные реализации codemod'ом `scripts/make_explicit.py`; потребители конкретных типов
|
||||
> перетипизированы на интерфейсы (8 мест в проде, 17 тест-файлов; самовызовы — `((ISessionClient)this)`);
|
||||
> 10 маркерных классов заменены маркерными интерфейсами (`IKanbanModule`…`ISharedKernel`); NSubstitute 6.1.0
|
||||
> подключён к 5 тест-проектам, эталон миграции — `FakePasswordHasher` → `TestHashers.New()` (фейк удалён);
|
||||
> правила зафиксированы в §11 код-стайла. Card/`I*Card` — implicit (DTO). Оставшиеся 30 фейков —
|
||||
> поэтапная миграция (`backlog.md`, TD-TESTS-NSUBSTITUTE). Build 5 sln 0/0, тесты зелёные.
|
||||
|
||||
**Все этапы 0–12 выполнены (100%)** — см. roadmap
|
||||
> `docs/superpowers/plans/2026-09-05-deal-roadmap.md`, план этапа 10
|
||||
|
||||
Reference in New Issue
Block a user