event-driven test waits, fail-loud on timeout (T-108)
Replaces the fixed Future.delayed sleeps the consultant flagged
with stream-based waits that complete when the awaited event
arrives. Timeout callbacks call fail() with a diagnostic instead
of `onTimeout: () {}` swallowing the signal — a never-producing
pty now reports "pty did not produce X within 5s" instead of an
unhelpful "Actual: ''".
session_test.dart:
- _readUntil helper subscribes to s.output, completes when a
marker substring appears (or onDone), fails on timeout.
- _waitForBuffer polls a buffer the listener is already filling
after a write; 25ms tick, 5s ceiling, fail-loud on miss.
- Drops the 500ms settle + 50×100ms polling pattern in the write
test; uses a "first-byte" completer for prompt-readiness.
- retry: 2 restored on the four read-dependent forkpty tests
(the underlying flutter-test-runner pty-output flake hasn't
fully gone away; recovers cleanly on a fresh spawn).
watcher_test.dart:
- "emits a created event" awaits stream.firstWhere instead of two
fixed sleeps.
- "filters ignored paths" uses pre + post sentinel markers to
bracket the inotify-delivery window event-driven; the negative
assertion only runs after the post marker is observed.
event_sink.dart:
- RecordingEventSink gains a broadcast `stream` for the same
event-await pattern. PaneRegistry's output test subscribes
BEFORE spawn so first bytes aren't lost.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1801,3 +1801,5 @@ INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by,
|
||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-100', 'status', 'in_progress', 'done', NULL, '2026-05-17 19:47:50', '2026-05-17 19:47:50', '2026-05-17 19:47:50', NULL, '7d3c0ad4c47d3271ac35c5159e6e9d0e', 1) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-105', 'status', 'backlog', 'in_progress', NULL, '2026-05-17 19:52:39', '2026-05-17 19:52:39', '2026-05-17 19:52:39', NULL, '129acb5d6b1882cb6ed4c9be46fd3e81', 1) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-105', 'status', 'in_progress', 'done', NULL, '2026-05-17 19:56:28', '2026-05-17 19:56:28', '2026-05-17 19:56:28', NULL, '62dfdadc31b2c231afd837fb46f0a114', 1) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-108', 'status', 'backlog', 'in_progress', NULL, '2026-05-17 19:58:13', '2026-05-17 19:58:13', '2026-05-17 19:58:13', NULL, 'a5dbfe5881e152e82538181b0fe56609', 1) ON CONFLICT(hash) DO NOTHING;
|
||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-108', 'status', 'in_progress', 'done', NULL, '2026-05-17 20:05:38', '2026-05-17 20:05:38', '2026-05-17 20:05:38', NULL, '6815472fbfaa6d7740945b42d4c87f57', 1) ON CONFLICT(hash) DO NOTHING;
|
||||
|
||||
@@ -1781,3 +1781,10 @@ INSERT INTO tickets (id, type, parent_id, title, description, status, priority,
|
||||
Depends on T-100 (ClideTappable accepting focus).
|
||||
|
||||
Source: consultants.md "UX — Findings — [Major] No focus-traversal wiring".', 'done', 'medium', NULL, NULL, NULL, '2026-05-17 18:47:47', '2026-05-17 19:56:28', NULL, '0715d1ded0d12083622f8a46d570f4d9', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
|
||||
INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-108', 'task', 'T-97', 'replace wall-clock sleeps in watcher_test / session_test with event-driven waits', '`test/files/watcher_test.dart:67-82` uses fixed `Future.delayed`. `test/pty/session_test.dart` polls 50×100ms and uses a bare `500ms` settle. `session_test.dart`''s `timeout(5s, onTimeout: () {})` swallows the timeout — a never-producing PTY proceeds to a confusing assertion failure rather than a clear timeout.
|
||||
|
||||
**Fix:**
|
||||
1. Replace fixed sleeps with `expectLater(stream, emits(...))` or equivalent event-driven waits.
|
||||
2. Replace swallowed `onTimeout: () {}` with `onTimeout: () => fail(''...'')`.
|
||||
|
||||
Source: consultants.md "Tests — Findings — [Major]".', 'done', 'medium', NULL, NULL, NULL, '2026-05-17 18:47:59', '2026-05-17 20:05:38', NULL, '33e15d84caed686e88fc42f1f4a3586c', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
|
||||
|
||||
Reference in New Issue
Block a user