mirror of
https://github.com/zjs81/meshcore-open.git
synced 2026-04-20 22:13:48 +00:00
Add error handling tests for USB connection and listing ports
This commit is contained in:
parent
524558c511
commit
25fc9454a8
3 changed files with 97 additions and 1 deletions
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
|
|
@ -23,6 +24,8 @@ class _FakeMeshCoreConnector extends MeshCoreConnector {
|
|||
String? fakeActiveUsbPort;
|
||||
String? fakeActiveUsbPortDisplayLabel;
|
||||
bool fakeUsbTransportConnected = false;
|
||||
Future<List<String>> Function()? listUsbPortsImpl;
|
||||
Future<void> Function({required String portName})? connectUsbImpl;
|
||||
|
||||
@override
|
||||
MeshCoreConnectionState get state => initialState;
|
||||
|
|
@ -38,13 +41,21 @@ class _FakeMeshCoreConnector extends MeshCoreConnector {
|
|||
bool get isUsbTransportConnected => fakeUsbTransportConnected;
|
||||
|
||||
@override
|
||||
Future<List<String>> listUsbPorts() async => List<String>.from(_ports);
|
||||
Future<List<String>> listUsbPorts() async {
|
||||
if (listUsbPortsImpl != null) {
|
||||
return listUsbPortsImpl!();
|
||||
}
|
||||
return List<String>.from(_ports);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> connectUsb({
|
||||
required String portName,
|
||||
int baudRate = 115200,
|
||||
}) async {
|
||||
if (connectUsbImpl != null) {
|
||||
return connectUsbImpl!(portName: portName);
|
||||
}
|
||||
connectUsbCalls += 1;
|
||||
lastConnectPortName = portName;
|
||||
}
|
||||
|
|
@ -145,4 +156,50 @@ void main() {
|
|||
expect(find.widgetWithText(FloatingActionButton, 'USB'), findsNothing);
|
||||
}
|
||||
});
|
||||
|
||||
group('Error Handling', () {
|
||||
testWidgets('shows error message when listing ports fails', (tester) async {
|
||||
final connector = _FakeMeshCoreConnector();
|
||||
connector.listUsbPortsImpl = () async {
|
||||
throw PlatformException(
|
||||
code: 'usb_permission_denied',
|
||||
message: 'Permission denied',
|
||||
);
|
||||
};
|
||||
|
||||
await tester.pumpWidget(
|
||||
_buildTestApp(connector: connector, child: const UsbScreen()),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(
|
||||
find.text('USB permission was denied.'),
|
||||
findsOneWidget,
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'connection failure completes without leaving loading state',
|
||||
(tester) async {
|
||||
final connector = _FakeMeshCoreConnector(
|
||||
ports: <String>['COM1'],
|
||||
);
|
||||
var connectAttempted = false;
|
||||
connector.connectUsbImpl = ({required String portName}) async {
|
||||
connectAttempted = true;
|
||||
throw PlatformException(code: 'usb_busy', message: 'Device is busy');
|
||||
};
|
||||
|
||||
await tester.pumpWidget(
|
||||
_buildTestApp(connector: connector, child: const UsbScreen()),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.widgetWithText(FilledButton, 'Connect'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(connectAttempted, isTrue);
|
||||
expect(find.byType(CircularProgressIndicator), findsNothing);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -138,4 +138,25 @@ void main() {
|
|||
expect(packets, hasLength(1));
|
||||
expect(packets.single.payload, orderedEquals(<int>[0x55]));
|
||||
});
|
||||
|
||||
test('recovers from invalid frame header', () {
|
||||
final decoder = UsbSerialFrameDecoder();
|
||||
|
||||
final packets = decoder.ingest(
|
||||
Uint8List.fromList(<int>[
|
||||
// First, a malformed frame (e.g. from a partial TX echo)
|
||||
usbSerialRxFrameStart,
|
||||
usbSerialTxFrameStart,
|
||||
// Then, a valid frame
|
||||
usbSerialRxFrameStart,
|
||||
0x01,
|
||||
0x00,
|
||||
0x88,
|
||||
]),
|
||||
);
|
||||
|
||||
expect(packets, hasLength(1));
|
||||
expect(packets.single.isRxFrame, isTrue);
|
||||
expect(packets.single.payload, orderedEquals(<int>[0x88]));
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,24 @@ void main() {
|
|||
},
|
||||
);
|
||||
|
||||
test('friendlyUsbPortName works for Linux-style label', () {
|
||||
expect(
|
||||
friendlyUsbPortName(
|
||||
'/dev/ttyACM0 - RAK4631 - USB VID:PID=239A:8029 SER=xxxxxxxx',
|
||||
),
|
||||
'RAK4631',
|
||||
);
|
||||
});
|
||||
|
||||
test('friendlyUsbPortName trims whitespace from label parts', () {
|
||||
expect(
|
||||
friendlyUsbPortName(
|
||||
' /dev/ttyS0 - My Serial Port - n/a ',
|
||||
),
|
||||
'My Serial Port',
|
||||
);
|
||||
});
|
||||
|
||||
test(
|
||||
'friendlyUsbPortName falls back to port name when description is n/a',
|
||||
() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue