drop the unused mocktail dep; amend D-25 (T-385)
mocktail was pinned and documented as the IO-mocking strategy, but after the T-91 coverage drive it had zero imports — every IO seam ended up with an injected hand-rolled fake instead. D-25 is amended to record that the hand-rolled-fakes rule covers IO seams too; licenses.yaml and the lockfile follow. The ptyc binary removal noted in this sweep landed with the git-API commit (it was already staged). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -66,7 +66,7 @@ You might also want, project-permitting:
|
||||
- [D-22: WCAG-AA contrast gate on bundled themes](decisions/accessibility.md#d-22-wcag-aa-contrast-gate-on-bundled-themes) — _accessibility_
|
||||
- [D-23: Test pyramid — seven layers](decisions/testing.md#d-23-test-pyramid--seven-layers) — _testing_
|
||||
- [D-24: Golden tests — primitives only, Alchemist + Ahem](decisions/testing.md#d-24-golden-tests--primitives-only-alchemist--ahem) — _testing_
|
||||
- [D-25: Mocks — mocktail at IO, hand-rolled fakes for ChangeNotifiers](decisions/testing.md#d-25-mocks--mocktail-at-io-hand-rolled-fakes-for-changenotifiers) — _testing_
|
||||
- [D-25: Mocks — hand-rolled fakes throughout; mocktail dropped](decisions/testing.md#d-25-mocks--hand-rolled-fakes-throughout-mocktail-dropped) — _testing_
|
||||
- [D-26: Web driver — raw Playwright + Flutter semantics](decisions/testing.md#d-26-web-driver--raw-playwright--flutter-semantics) — _testing_
|
||||
- [D-27: Startup regression gate](decisions/testing.md#d-27-startup-regression-gate) — _testing_
|
||||
- [D-28: Test organisation — mirror `lib/` in `test/`](decisions/testing.md#d-28-test-organisation--mirror-lib-in-test) — _testing_
|
||||
|
||||
@@ -73,7 +73,7 @@ Core, rendering, IPC, kernel, panel manager.
|
||||
### D-10: State management — `ChangeNotifier` + `ListenableBuilder`
|
||||
- **Date:** 2026-04-21
|
||||
- **Decision:** Per-feature state uses `ChangeNotifier` exposed through a feature facade (singleton-per-kernel); widgets subscribe via `ListenableBuilder`. No Riverpod, Provider, BLoC, or Redux.
|
||||
- **Rationale:** SDK-shipped, zero deps, trivial to fake in tests (hand-rolled fakes in [D-25](testing.md#d-25-mocks--mocktail-at-io-hand-rolled-fakes-for-changenotifiers)). Violates [D-31 prefer-zero-deps](tooling.md#d-31-prefer-zero-deps-exact-pin) otherwise. See [R-8](../rejected/architecture.md#r-8-riverpod--provider--bloc-for-state).
|
||||
- **Rationale:** SDK-shipped, zero deps, trivial to fake in tests (hand-rolled fakes in [D-25](testing.md#d-25-mocks--hand-rolled-fakes-throughout-mocktail-dropped)). Violates [D-31 prefer-zero-deps](tooling.md#d-31-prefer-zero-deps-exact-pin) otherwise. See [R-8](../rejected/architecture.md#r-8-riverpod--provider--bloc-for-state).
|
||||
- **Cost:** No codegen ergonomics; manual `notifyListeners()` discipline. The `ListenableBuilder.listenable` contract rejects rebuilds outside the subscribed notifier — intentional.
|
||||
- **Raised by:** 2026-04-21 planning.
|
||||
|
||||
|
||||
@@ -18,10 +18,10 @@ Test pyramid, drivers, client-side constraint.
|
||||
- **Cost:** Goldens have zero real text; layouts rely on widget tests. Acceptable.
|
||||
- **Raised by:** 2026-04-21 planning.
|
||||
|
||||
### D-25: Mocks — mocktail at IO, hand-rolled fakes for ChangeNotifiers
|
||||
- **Date:** 2026-04-21
|
||||
- **Decision:** `mocktail 1.0.4` mocks IO boundaries (sockets, processes, `dart:io` File/Directory). `ChangeNotifier` facades get hand-rolled fakes — tiny classes that extend `ChangeNotifier` with test-controlled setters. No `mocktail` for notifiers.
|
||||
- **Rationale:** Mocking a `ChangeNotifier` with a generated mock hides subscription bugs — `notifyListeners` becomes a mock call instead of actually firing. Hand-rolled fakes exercise the real subscription machinery.
|
||||
### D-25: Mocks — hand-rolled fakes throughout; mocktail dropped
|
||||
- **Date:** 2026-04-21 (amended 2026-06-12)
|
||||
- **Decision:** Test doubles are hand-rolled fakes — tiny classes that extend the real base (`ChangeNotifier` facades, `StreamJsonProcess`, `DaemonClient`) with test-controlled setters. **Amendment (2026-06-12, T-385):** `mocktail` was originally pinned for IO boundaries, but after the T-91 coverage drive it had zero imports — every IO seam ended up with an injected hand-rolled fake (`FakeDaemonClient`, fake process factories, recording event sinks) instead. The unused dep is dropped; the no-mocks-for-notifiers rule stands and in practice covers IO seams too.
|
||||
- **Rationale:** Mocking a `ChangeNotifier` with a generated mock hides subscription bugs — `notifyListeners` becomes a mock call instead of actually firing. Hand-rolled fakes exercise the real subscription machinery. The same held at IO seams: constructor-injected fakes kept tests on real control flow.
|
||||
- **Cost:** Roughly 20 lines per fake. Rounds out to less code than configuring a mocktail whenCall chain.
|
||||
- **Raised by:** 2026-04-21 planning.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user