@@ -51,6 +51,7 @@ class MockServerChannel implements ServerCommunicationChannel {
51
51
new StreamController <Response >.broadcast ();
52
52
StreamController <Notification > notificationController =
53
53
new StreamController <Notification >(sync : true );
54
+ Completer <Response > errorCompleter;
54
55
55
56
List <Response > responsesReceived = [];
56
57
List <Notification > notificationsReceived = [];
@@ -81,23 +82,34 @@ class MockServerChannel implements ServerCommunicationChannel {
81
82
return ;
82
83
}
83
84
notificationsReceived.add (notification);
85
+ if (errorCompleter != null && notification.event == 'server.error' ) {
86
+ errorCompleter.completeError (
87
+ new ServerError (notification.params['message' ]),
88
+ new StackTrace .fromString (notification.params['stackTrace' ]));
89
+ }
84
90
// Wrap send notification in future to simulate websocket
85
91
// TODO(scheglov) ask Dan why and decide what to do
86
92
// new Future(() => notificationController.add(notification));
87
93
notificationController.add (notification);
88
94
}
89
95
90
96
/**
91
- * Simulate request/response pair.
97
+ * Send the given [request] to the server and return a future that will
98
+ * complete when a response associated with the [request] has been received.
99
+ * The value of the future will be the received response. If [throwOnError] is
100
+ * `true` (the default) then the returned future will throw an exception if a
101
+ * server error is reported before the response has been received.
92
102
*/
93
- Future <Response > sendRequest (Request request) {
103
+ Future <Response > sendRequest (Request request, {bool throwOnError = true }) {
104
+ // TODO(brianwilkerson) Attempt to remove the `throwOnError` parameter and
105
+ // have the default behavior be the only behavior.
94
106
// No further requests should be sent after the connection is closed.
95
107
if (_closed) {
96
108
throw new Exception ('sendRequest after connection closed' );
97
109
}
98
110
// Wrap send request in future to simulate WebSocket.
99
111
new Future (() => requestController.add (request));
100
- return waitForResponse (request);
112
+ return waitForResponse (request, throwOnError : throwOnError );
101
113
}
102
114
103
115
@override
@@ -111,10 +123,28 @@ class MockServerChannel implements ServerCommunicationChannel {
111
123
new Future (() => responseController.add (response));
112
124
}
113
125
114
- Future <Response > waitForResponse (Request request) {
126
+ /**
127
+ * Return a future that will complete when a response associated with the
128
+ * given [request] has been received. The value of the future will be the
129
+ * received response. If [throwOnError] is `true` (the default) then the
130
+ * returned future will throw an exception if a server error is reported
131
+ * before the response has been received.
132
+ *
133
+ * Unlike [sendRequest] , this method assumes that the [request] has already
134
+ * been sent to the server.
135
+ */
136
+ Future <Response > waitForResponse (Request request,
137
+ {bool throwOnError = true }) {
138
+ // TODO(brianwilkerson) Attempt to remove the `throwOnError` parameter and
139
+ // have the default behavior be the only behavior.
115
140
String id = request.id;
116
- return responseController.stream
117
- .firstWhere ((response) => response.id == id);
141
+ Future <Response > response =
142
+ responseController.stream.firstWhere ((response) => response.id == id);
143
+ if (throwOnError) {
144
+ errorCompleter ?? = new Completer <Response >();
145
+ return Future .any ([response, errorCompleter.future]);
146
+ }
147
+ return response;
118
148
}
119
149
}
120
150
@@ -194,6 +224,16 @@ class MockSource extends StringTypedMock implements Source {
194
224
bool exists () => null ;
195
225
}
196
226
227
+ class ServerError implements Exception {
228
+ final message;
229
+
230
+ ServerError (this .message);
231
+
232
+ String toString () {
233
+ return "Server Error: $message " ;
234
+ }
235
+ }
236
+
197
237
class StringTypedMock {
198
238
String _toString;
199
239
0 commit comments