feat: add Flutter desktop client for Rtty

This commit is contained in:
2026-08-01 17:40:52 +08:00
parent f25506ec5b
commit 93ee801f27
31 changed files with 2679 additions and 0 deletions

View File

@@ -0,0 +1,61 @@
// 端到端集成测试:桌面端连接层 ↔ Rust 服务端。
//
// 运行前需先启动 Rust 服务端cd .. && cargo run
// 运行flutter test test/e2e_ws_test.dart
import 'dart:io';
import 'package:flutter_test/flutter_test.dart';
import 'package:xterm/xterm.dart';
import '../lib/src/rtty_client.dart';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
test('RttyClient connects to Rust server and renders command output',
() async {
final terminal = Terminal();
final client = RttyClient(terminal);
final states = <ConnState>[];
String? sessionId;
final raw = StringBuffer();
client.onStateChanged = (s) => states.add(s);
client.onReady = (id, cols, rows) => sessionId = '$id:$cols:$rows';
client.onRawData = (d) => raw.write(d);
await client.connect(host: '127.0.0.1', port: 8080);
// 等待连接就绪socket 已连接 + 收到 ready 帧)。
final deadline = DateTime.now().add(const Duration(seconds: 5));
while ((!client.isConnected || sessionId == null) &&
DateTime.now().isBefore(deadline)) {
await Future<void>.delayed(const Duration(milliseconds: 100));
}
expect(client.isConnected, isTrue,
reason: '未能连接服务端 states=$states');
expect(sessionId, isNotNull,
reason: '未收到 ready 帧 states=$states');
// 发送命令,等待回显。
client.sendInput('echo RTTY_E2E_${DateTime.now().millisecondsSinceEpoch}\r\n');
String? matchedLine;
final outDeadline = DateTime.now().add(const Duration(seconds: 8));
while (DateTime.now().isBefore(outDeadline)) {
await Future<void>.delayed(const Duration(milliseconds: 150));
final text = raw.toString();
final lines = text.split('\n');
matchedLine = lines.where((l) => l.contains('RTTY_E2E')).lastOrNull;
if (matchedLine != null) break;
}
expect(matchedLine, isNotNull,
reason: '未捕获到命令回显。流末尾:'
'${raw.toString().split('').length > 200 ? raw.toString().substring(raw.toString().length - 200) : raw.toString()}');
await client.disconnect();
expect(client.state, ConnState.disconnected);
});
}