test: drive the real UI against an in-memory runner
FakeIperf3Runner implements Iperf3Runner, so the widget tests exercise the actual widget tree — GO, STOP, the status line, the stat row, validation — with no MethodChannel and no native library. That was impossible while the screen constructed its own Iperf3Service. The view model tests share the same fake instead of each file carrying a double that had to mirror the concrete service. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:iperf3gui/domain/models/iperf3_event.dart';
|
||||
import 'package:iperf3gui/domain/models/iperf3_result.dart';
|
||||
import 'package:iperf3gui/domain/models/test_configuration.dart';
|
||||
import 'package:iperf3gui/domain/services/iperf3_runner.dart';
|
||||
|
||||
/// In-memory [Iperf3Runner] for tests.
|
||||
///
|
||||
/// Implements the interface rather than the concrete service, so it tracks the
|
||||
/// five members the UI actually depends on instead of every public member the
|
||||
/// MethodChannel implementation happens to have.
|
||||
class FakeIperf3Runner implements Iperf3Runner {
|
||||
FakeIperf3Runner({this.onRun});
|
||||
|
||||
/// Supplies the result for each [run], and may [emit] events first.
|
||||
Future<Iperf3Result> Function(TestConfiguration)? onRun;
|
||||
|
||||
final StreamController<Iperf3Event> _controller =
|
||||
StreamController<Iperf3Event>.broadcast();
|
||||
|
||||
/// Configurations passed to [run], in order.
|
||||
final List<TestConfiguration> runCalls = [];
|
||||
|
||||
int stopCallCount = 0;
|
||||
bool disposed = false;
|
||||
bool _isRunning = false;
|
||||
|
||||
int get runCallCount => runCalls.length;
|
||||
|
||||
/// Push an event as if the native layer had reported it.
|
||||
void emit(Iperf3Event event) => _controller.add(event);
|
||||
|
||||
@override
|
||||
Stream<Iperf3Event> get events => _controller.stream;
|
||||
|
||||
@override
|
||||
bool get isRunning => _isRunning;
|
||||
|
||||
@override
|
||||
Future<Iperf3Result> run(TestConfiguration config) async {
|
||||
runCalls.add(config);
|
||||
_isRunning = true;
|
||||
try {
|
||||
if (onRun != null) return await onRun!(config);
|
||||
return const Iperf3Result(rawOutput: '', exitCode: 0);
|
||||
} finally {
|
||||
_isRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> stop() async {
|
||||
stopCallCount++;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {
|
||||
disposed = true;
|
||||
await _controller.close();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user