@@ -18,16 +18,31 @@ import 'package:watcher/watcher.dart';
1818class MockServerChannel implements ServerCommunicationChannel {
1919 /// A controller for the stream of requests and responses from the client to
2020 /// the server.
21+ ///
22+ /// Messages added to this stream should be converted to/from JSON to ensure
23+ /// they are fully serialized/deserialized as they would be in a real server
24+ /// otherwise tests may receive real instances where in reality they would be
25+ /// maps.
2126 StreamController <RequestOrResponse > requestController =
2227 StreamController <RequestOrResponse >();
2328
2429 /// A controller for the stream of requests and responses from the server to
2530 /// the client.
31+ ///
32+ /// Messages added to this stream should be converted to/from JSON to ensure
33+ /// they are fully serialized/deserialized as they would be in a real server
34+ /// otherwise tests may receive real instances where in reality they would be
35+ /// maps.
2636 StreamController <RequestOrResponse > responseController =
2737 StreamController <RequestOrResponse >.broadcast ();
2838
2939 /// A controller for the stream of notifications from the server to the
3040 /// client.
41+ ///
42+ /// Unlike [requestController] and [responseController] , notifications added
43+ /// here are not round-tripped through JSON but instead have real class
44+ /// instances as their `params` . This is because they are only used by tests
45+ /// which will cast and/or switch on the types for convenience.
3146 StreamController <Notification > notificationController =
3247 StreamController <Notification >.broadcast (sync : true );
3348
@@ -67,7 +82,10 @@ class MockServerChannel implements ServerCommunicationChannel {
6782 if (_closed) {
6883 return ;
6984 }
85+
7086 notificationsReceived.add (notification);
87+ notificationController.add (notification);
88+
7189 var errorCompleter = this .errorCompleter;
7290 if (errorCompleter != null && notification.event == 'server.error' ) {
7391 var params = notification.params! ;
@@ -77,14 +95,17 @@ class MockServerChannel implements ServerCommunicationChannel {
7795 StackTrace .fromString (params['stackTrace' ] as String ),
7896 );
7997 }
80- // Wrap send notification in future to simulate websocket
81- // TODO(scheglov): ask Dan why and decide what to do
82- // new Future(() => notificationController.add(notification));
83- notificationController.add (notification);
8498 }
8599
86100 @override
87101 void sendRequest (Request request) {
102+ // Round-trip via JSON to ensure all types are fully serialized as they
103+ // would be in a real setup.
104+ request =
105+ Request .fromJson (
106+ jsonDecode (jsonEncode (request.toJson ())) as Map <String , Object ?>,
107+ )! ;
108+
88109 serverRequestsSent.add (request);
89110 responseController.add (request);
90111 }
@@ -95,9 +116,16 @@ class MockServerChannel implements ServerCommunicationChannel {
95116 if (_closed) {
96117 return ;
97118 }
119+
120+ // Round-trip via JSON to ensure all types are fully serialized as they
121+ // would be in a real setup.
122+ response =
123+ Response .fromJson (
124+ jsonDecode (jsonEncode (response.toJson ())) as Map <String , Object ?>,
125+ )! ;
126+
98127 responsesReceived.add (response);
99- // Wrap send response in future to simulate WebSocket.
100- Future (() => responseController.add (response));
128+ responseController.add (response);
101129 }
102130
103131 /// Send the given [request] to the server as if it had been sent from the
@@ -117,8 +145,7 @@ class MockServerChannel implements ServerCommunicationChannel {
117145 jsonDecode (jsonEncode (request)) as Map <String , Object ?>,
118146 )! ;
119147
120- // Wrap send request in future to simulate WebSocket.
121- unawaited (Future (() => requestController.add (request)));
148+ requestController.add (request);
122149 var response = await waitForResponse (request);
123150
124151 // Round-trip via JSON to ensure all types are fully serialized as they
@@ -133,13 +160,20 @@ class MockServerChannel implements ServerCommunicationChannel {
133160
134161 /// Send the given [response] to the server as if it had been sent from the
135162 /// client.
136- Future < void > simulateResponseFromClient (Response response) {
163+ void simulateResponseFromClient (Response response) {
137164 // No further requests should be sent after the connection is closed.
138165 if (_closed) {
139166 throw Exception ('simulateRequestFromClient after connection closed' );
140167 }
141- // Wrap send request in future to simulate WebSocket.
142- return Future (() => requestController.add (response));
168+
169+ // Round-trip via JSON to ensure all types are fully serialized as they
170+ // would be in a real setup.
171+ response =
172+ Response .fromJson (
173+ jsonDecode (jsonEncode (response)) as Map <String , Object ?>,
174+ )! ;
175+
176+ requestController.add (response);
143177 }
144178
145179 /// Return a future that will complete when a response associated with the
0 commit comments