import 'package:protobuf/protobuf.dart'; import 'package:test/test.dart'; import 'package:toki_socket/toki_socket.dart'; class _FakeCommunicator extends Communicator { final sentPackets = []; _FakeCommunicator() { isAlive = true; initialize({ TestData.getDefault().info_.qualifiedMessageName: TestData.fromBuffer, HeartBeat.getDefault().info_.qualifiedMessageName: HeartBeat.fromBuffer, }); } @override Future transmitPacket(PacketBase base) async { sentPackets.add(base); } void closeForTest() { isAlive = false; cancelPendingRequests(); } @override Future send(T data) async { if (isAlive) { await queuePacket(PacketBase() ..typeName = data.info_.qualifiedMessageName ..nonce = ++nonce ..data = data.writeToBuffer()); } return Future.value(); } } void main() { group('Communicator protocol guards', () { test('response typeName mismatch completes sendRequest with error', () async { final communicator = _FakeCommunicator(); final future = communicator.sendRequest( TestData() ..index = 1 ..message = 'hello', ); await Future.delayed(Duration.zero); final requestNonce = communicator.sentPackets.single.nonce; communicator.onReceivedData( HeartBeat.getDefault().info_.qualifiedMessageName, HeartBeat().writeToBuffer(), responseNonce: requestNonce, ); await expectLater( future, throwsA( isA().having((error) => error.toString(), 'message', contains('Response type mismatch')), ), ); }); test('close 후 sendRequest는 StateError로 완료된다', () async { final communicator = _FakeCommunicator(); final future = communicator.sendRequest( TestData()..index = 1, ); await Future.delayed(Duration.zero); communicator.closeForTest(); await expectLater( future, throwsA( isA().having( (error) => error.message, 'message', contains('connection closed'), ), ), ); }); test( 'cannot register addRequestListener for a type already using addListener', () { final communicator = _FakeCommunicator(); communicator.addListener((_) {}); expect( () => communicator.addRequestListener( (req) async => TestData()..index = req.index, ), throwsA(isA()), ); }); test( 'cannot register addListener for a type already using addRequestListener', () { final communicator = _FakeCommunicator(); communicator.addRequestListener( (req) async => TestData()..index = req.index, ); expect( () => communicator.addListener((_) {}), throwsA(isA()), ); }); }); }