95acf5ea38
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>
63 lines
1.7 KiB
Dart
63 lines
1.7 KiB
Dart
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();
|
|
}
|
|
}
|