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:
@@ -7,6 +7,8 @@
|
||||
/// (server depends on subsystems, not the other way round).
|
||||
library;
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import '../ipc/envelope.dart';
|
||||
|
||||
abstract class DaemonEventSink {
|
||||
@@ -16,10 +18,20 @@ abstract class DaemonEventSink {
|
||||
/// In-memory recording sink for tests + for composing multi-sink
|
||||
/// scenarios (e.g. tee to both the wire and an audit log).
|
||||
class RecordingEventSink implements DaemonEventSink {
|
||||
RecordingEventSink();
|
||||
final List<IpcEvent> events = [];
|
||||
final _controller = StreamController<IpcEvent>.broadcast();
|
||||
|
||||
@override
|
||||
void emit(IpcEvent event) => events.add(event);
|
||||
void emit(IpcEvent event) {
|
||||
events.add(event);
|
||||
_controller.add(event);
|
||||
}
|
||||
|
||||
/// Live stream of every event emitted into this sink. Tests use
|
||||
/// `stream.firstWhere(...)` for event-driven waits instead of
|
||||
/// polling the [events] list with `Future.delayed`.
|
||||
Stream<IpcEvent> get stream => _controller.stream;
|
||||
|
||||
/// Convenience: filter to a single subsystem (`pane`, `git`, …).
|
||||
Iterable<IpcEvent> ofSubsystem(String subsystem) => events.where((e) => e.subsystem == subsystem);
|
||||
|
||||
Reference in New Issue
Block a user