Files
slm-design/DRAFT/level-2/domains/testing.md

190 lines
8.2 KiB
Markdown
Raw Normal View History

# Тестирование доменного пакета
2026-08-02 22:53:05 +03:00
> Проверка Domain API, port contracts, production wiring и framework projections Level 2.
2026-07-30 20:48:05 +03:00
## Связанные правила
- [`SLM-L2-TEST-R016`](../../rules/level-2.md#slm-l2-test-r016)
2026-08-02 22:53:05 +03:00
- [`SLM-L2-API-A019`](../../rules/level-2.md#slm-l2-api-a019)
- [`SLM-L2-ASSEMBLY-A020`](../../rules/level-2.md#slm-l2-assembly-a020)
2026-07-30 20:48:05 +03:00
- [`SLM-L2-ADAPTER-R021`](../../rules/level-2.md#slm-l2-adapter-r021)
2026-08-02 22:53:05 +03:00
- [`SLM-L2-API-A022`](../../rules/level-2.md#slm-l2-api-a022)
- [`SLM-L2-ASSEMBLY-R023`](../../rules/level-2.md#slm-l2-assembly-r023)
2026-08-02 22:53:05 +03:00
- [`SLM-L2-API-R024`](../../rules/level-2.md#slm-l2-api-r024)
- [`SLM-L2-PORT-R027`](../../rules/level-2.md#slm-l2-port-r027)
- [`SLM-L2-REALTIME-R029`](../../rules/level-2.md#slm-l2-realtime-r029)
- [`SLM-L2-ASSEMBLY-R030`](../../rules/level-2.md#slm-l2-assembly-r030)
## Размещение
2026-08-02 22:53:05 +03:00
Тест находится рядом с module-owner проверяемой ответственности. У доменного пакета нет общей корневой папки `tests`.
| Проверяемая граница | Владелец теста |
|---|---|
2026-08-02 22:53:05 +03:00
| Domain API operations, models, outcomes и errors | `api` через factory |
| Deterministic runtime и guards | `api` |
| Реализация dependency port | Adapter |
| Default и специальный production graph | Assembly |
| Provider, hook, query/store integration и hydration | Framework binding |
| Cross-domain graph | Graph owner |
2026-08-02 22:53:05 +03:00
## Domain API через фабрику
2026-08-02 22:53:05 +03:00
Каждый публичный сценарий проверяется через фабрику владеющего им Domain API с управляемыми fake ports:
```ts
2026-08-02 22:53:05 +03:00
import type {
AuthSessionApi,
} from '@/domains/auth/api'
import type {
AuthIdentityPort,
} from '@/domains/auth/api/ports'
2026-07-30 20:48:05 +03:00
import {
2026-08-02 22:53:05 +03:00
createAuthSessionApi,
} from '@/domains/auth/api/factory'
const identity: AuthIdentityPort = createIdentityPortFake({
signIn: {
ok: true,
value: {
expiresAt: 1_700_000_000_000,
subject: 'user-1',
},
},
})
const api: AuthSessionApi = createAuthSessionApi({
identity,
runtime: {
createId: () => 'id-1',
now: () => 1_700_000_000_000,
},
})
```
API suite проверяет:
- public models и outcomes;
- validation commands и port records;
- mapping каждого expected port failure;
- отсутствие raw provider details в domain errors;
- cancellation и outcome uncertainty при наличии;
- pure transitions и reconciliation;
- каждый API отдельно при нескольких factories.
API-тест не использует React, production assembly, реальный SDK, backend, system clock или module singleton.
## Adapter contract test
Adapter test доказывает, что concrete provider реализует port:
- правильно преобразует arguments;
- валидно читает provider record;
- возвращает port record, а не raw DTO;
- различает закрытые port failures;
- не создаёт public domain error;
- соблюдает cancellation, timeout и lifecycle contract;
- использует заявленный environment capability set.
Fake port в API-тесте не заменяет adapter contract test. Идеальный fake может соответствовать типу, пока реальный endpoint или SDK уже изменился.
## Default assembly
2026-07-30 20:48:05 +03:00
2026-08-02 22:53:05 +03:00
Тест `assemblies/default` проверяет:
2026-08-02 22:53:05 +03:00
- вызов только нужных API factories;
- выбор штатных adapter modules;
- точный именованный состав graph;
- объявленный baseline capability set;
- отсутствие module-import side effects;
- передачу cross-domain API аргументом;
- отсутствие factory/adapter leakage наружу;
- aggregate cleanup, если assembly создаёт owned resource или получает adapter lifecycle handle.
Каждая дополнительная assembly тестирует отличие своего production context, а не повторяет полный API suite.
## Partial construction и cleanup
Assembly test моделирует ошибку после регистрации каждого cleanup obligation, включая adapter-owned handle:
```text
resource A created
resource B creation failed
→ cleanup A awaited
→ original failure propagated
```
2026-08-02 22:53:05 +03:00
Проверяются reverse dependency order, idempotent repeated disposal, попытка очистить все resources и отсутствие callbacks после завершившегося cleanup.
2026-08-02 22:53:05 +03:00
Assembly без cleanup obligations не тестирует пустой `dispose`, потому что не обязана его предоставлять. Если adapter передал lifecycle handle, obligation существует независимо от resource ownership.
2026-08-02 22:53:05 +03:00
## Framework binding
2026-08-02 22:53:05 +03:00
Framework test получает fake готового Domain API и проверяет собственную responsibility:
2026-08-02 22:53:05 +03:00
- Provider и hook;
- query keys, stale policy и invalidation;
- store projection;
- optimistic update через API-owned function;
- hydration payload;
- public domain errors;
- subscription cleanup;
- отсутствие direct SDK/external source access.
2026-08-02 22:53:05 +03:00
Framework test не повторяет validation и failure mapping всех API operations.
2026-08-02 22:53:05 +03:00
## Realtime
2026-08-02 22:53:05 +03:00
API realtime test с fake port проверяет public events, stable errors, acknowledgement semantics и `OUTCOME_UNKNOWN` mapping.
2026-08-02 22:53:05 +03:00
Adapter realtime contract test проверяет:
2026-08-02 22:53:05 +03:00
- command correlation;
- duplicate и late acknowledgement;
- disconnect до ACK;
- ordering и sequence gaps;
- reconnect и resync;
- malformed frames;
- cancellation и unsubscribe;
- отсутствие callbacks после cleanup.
Assembly test отдельно проверяет shared connection, multiplexing, rollback и graph-level disposal. Framework test проверяет только materialization events и invalidation.
2026-08-02 22:53:05 +03:00
## SSR, RSC и Server Actions
2026-08-02 22:53:05 +03:00
Environment tests подтверждают:
2026-08-02 22:53:05 +03:00
- request-scoped API и cache не разделяются между users;
- API instance не входит в hydration payload;
- Client Component создаёт отдельный client graph;
- SSR-enabled Client Component проверяется в server prerender и browser hydration graphs;
- browser-only effect не выполняется во время server render;
- Server Action создаёт и очищает graph на каждый вызов;
- framework reference edge не превращается в executable client/server leak;
- `default` проверяется под всеми объявленными resolver conditions.
## Cross-domain graph
Graph owner test создаёт assemblies и construction points модулей Level 1 в dependency order и проверяет runtime inputs и callbacks. Отдельно проверяется невозможность mixed L1/L2 циклической сборки и reverse cleanup order.
Не достаточно проверить только статический import DAG: runtime dependencies, передаваемые arguments, должны быть представлены architecture mapping или review evidence.
## Автоматические структурные проверки
2026-07-30 20:48:05 +03:00
2026-08-02 22:53:05 +03:00
Import и export checks подтверждают:
2026-08-02 22:53:05 +03:00
- отсутствие root API пакета и Groups;
- обязательные `api`, `api/factory` и `assemblies/default`;
- `api/ports` только при наличии declared ports;
- допустимые exports каждого фасета;
- importer matrix factories, ports и concrete adapters;
- отсутствие deep imports;
- отсутствие SDK, framework и state/query runtime в graph `api`;
- отсутствие запрещённых cross-domain imports;
- environment compatibility под configured conditions;
- отсутствие статических cycles.
2026-07-30 20:48:05 +03:00
2026-08-02 22:53:05 +03:00
Runtime tests не заменяют import-graph checks и architecture review.