import 'dart:typed_data'; import 'package:ch934x_serial/ch934x_serial.dart'; import 'package:ch934x_serial/ch934x_serial_method_channel.dart'; import 'package:ch934x_serial/ch934x_serial_platform_interface.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; /// 用 mock 替代真实平台,以便在宿主测试中验证上层调用。 class _MockCh934xSerialPlatform extends Ch934xSerialPlatform with MockPlatformInterfaceMixin { _MockCh934xSerialPlatform({ // ignore: unused_element_parameter this.deviceList = const [], // ignore: unused_element_parameter this.serialNumber, // ignore: unused_element_parameter this.deviceType = Ch934xDeviceType.ch9344, // ignore: unused_element_parameter this.ports = const [], // ignore: unused_element_parameter this.openResult = true, // ignore: unused_element_parameter this.closeResult = true, // ignore: unused_element_parameter this.readBytes, // ignore: unused_element_parameter this.writeResult = 0, // ignore: unused_element_parameter this.gpioOutputResult = true, // ignore: unused_element_parameter this.gpioInput = 1, // ignore: unused_element_parameter this.modemControlResult = true, // ignore: unused_element_parameter this.modemStatus = ModemStatus.cts, }); List deviceList; String? serialNumber; int deviceType; List ports; bool openResult; bool closeResult; Uint8List? readBytes; int writeResult; bool gpioOutputResult; int gpioInput; bool modemControlResult; int modemStatus; @override Future> getDeviceList() async => deviceList; @override Future getSerialNumber(int deviceId) async => serialNumber; @override Future getDeviceType(int deviceId) async => deviceType; @override Future> getSerialPortList( int deviceId, { required int interfaceNumber, }) async => ports; @override Future openPort(Ch934xPortTarget target) async => openResult; @override Future closePort() async => closeResult; @override Future read(int length) async => readBytes ?? Uint8List(0); @override Future write(Uint8List data) async => writeResult; @override Future setGpioOutput({ required int gpioNumber, required int level, }) async => gpioOutputResult; @override Future getGpioInput(int gpioNumber) async => gpioInput; @override Future setModemControl({required int dtr, required int rts}) async => modemControlResult; @override Future getModemStatus() async => modemStatus; @override Future setExceptionCallback( void Function(Ch934xException exception) onException, ) async {} } void main() { TestWidgetsFlutterBinding.ensureInitialized(); test('默认平台实现是 MethodChannelCh934xSerial', () { expect(Ch934xSerialPlatform.instance, isInstanceOf()); }); test('Ch934xSerial 委托 platform 调用 getDeviceList', () async { final mock = _MockCh934xSerialPlatform( deviceList: const [ Ch934xDeviceInfo( deviceId: 1, vendorId: 0x1a86, productId: 0xfe0c, deviceType: Ch934xDeviceType.ch9344, serialNumber: 'SN-1', ), ], ); final plugin = Ch934xSerial.withPlatform(mock); final list = await plugin.getDeviceList(); expect(list.single.serialNumber, 'SN-1'); }); test('ModemStatus.isSet 按位与工作', () { const status = ModemStatus.cts | ModemStatus.dcd; expect(ModemStatus.isSet(status, ModemStatus.cts), isTrue); expect(ModemStatus.isSet(status, ModemStatus.dsr), isFalse); }); test('Ch934xPortTarget.toMap 字段可被 MethodChannel 直接消费', () { const target = Ch934xPortTarget( deviceId: 2, interfaceNumber: 1, serialPortIndex: 3, ); expect(target.toMap(), { 'deviceId': 2, 'interfaceNumber': 1, 'serialPortIndex': 3, }); }); test('Ch934xException.toString 汇总关键字段', () { final ex = Ch934xException( type: Ch934xExceptionType.deviceDetached, message: '设备被拔出', ); expect(ex.toString(), contains('deviceDetached')); expect(ex.toString(), contains('设备被拔出')); }); }