Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Side by Side Diff: pkg/analysis_server/test/channel_test.dart

Issue 544693002: Split channels library. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 library test.channel;
6
7 import 'dart:async';
8 import 'dart:convert';
9 import 'dart:io';
10
11 import 'package:analysis_server/src/channel.dart';
12 import 'package:analysis_server/src/protocol.dart' hide Error;
13 import 'package:unittest/unittest.dart';
14
15 import 'mocks.dart';
16
17 main() {
18 group('WebSocketChannel', () {
19 setUp(WebSocketChannelTest.setUp);
20 test('close', WebSocketChannelTest.close);
21 test('invalidJsonToClient', WebSocketChannelTest.invalidJsonToClient);
22 test('invalidJsonToServer', WebSocketChannelTest.invalidJsonToServer);
23 test('notification', WebSocketChannelTest.notification);
24 test('notificationAndResponse', WebSocketChannelTest.notificationAndResponse );
25 test('request', WebSocketChannelTest.request);
26 test('requestResponse', WebSocketChannelTest.requestResponse);
27 test('response', WebSocketChannelTest.response);
28 });
29 group('ByteStreamClientChannel', () {
30 setUp(ByteStreamClientChannelTest.setUp);
31 test('close', ByteStreamClientChannelTest.close);
32 test('listen_notification', ByteStreamClientChannelTest.listen_notification) ;
33 test('listen_response', ByteStreamClientChannelTest.listen_response);
34 test('sendRequest', ByteStreamClientChannelTest.sendRequest);
35 });
36 group('ByteStreamServerChannel', () {
37 setUp(ByteStreamServerChannelTest.setUp);
38 test('closed', ByteStreamServerChannelTest.closed);
39 test('listen_wellFormedRequest',
40 ByteStreamServerChannelTest.listen_wellFormedRequest);
41 test('listen_invalidRequest',
42 ByteStreamServerChannelTest.listen_invalidRequest);
43 test('listen_invalidJson', ByteStreamServerChannelTest.listen_invalidJson);
44 test('listen_streamError', ByteStreamServerChannelTest.listen_streamError);
45 test('listen_streamDone', ByteStreamServerChannelTest.listen_streamDone);
46 test('sendNotification', ByteStreamServerChannelTest.sendNotification);
47 test('sendResponse', ByteStreamServerChannelTest.sendResponse);
48 });
49 }
50
51 class WebSocketChannelTest {
52 static MockSocket socket;
53 static WebSocketClientChannel client;
54 static WebSocketServerChannel server;
55
56 static List requestsReceived;
57 static List responsesReceived;
58 static List notificationsReceived;
59
60 static void setUp() {
61 socket = new MockSocket.pair();
62 client = new WebSocketClientChannel(socket);
63 server = new WebSocketServerChannel(socket.twin);
64
65 requestsReceived = [];
66 responsesReceived = [];
67 notificationsReceived = [];
68
69 // Allow multiple listeners on server side for testing.
70 socket.twin.allowMultipleListeners();
71
72 server.listen(requestsReceived.add);
73 client.responseStream.listen(responsesReceived.add);
74 client.notificationStream.listen(notificationsReceived.add);
75 }
76
77 static Future close() {
78 var timeout = new Duration(seconds: 1);
79 var future = client.responseStream.drain().timeout(timeout);
80 client.close();
81 return future;
82 }
83
84 static Future invalidJsonToClient() {
85 var result = client.responseStream
86 .first
87 .timeout(new Duration(seconds: 1))
88 .then((Response response) {
89 expect(response.id, equals('myId'));
90 expectMsgCount(responseCount: 1);
91 });
92 socket.twin.add('{"foo":"bar"}');
93 server.sendResponse(new Response('myId'));
94 return result;
95 }
96
97 static Future invalidJsonToServer() {
98 var result = client.responseStream
99 .first
100 .timeout(new Duration(seconds: 1))
101 .then((Response response) {
102 expect(response.id, equals(''));
103 expect(response.error, isNotNull);
104 expectMsgCount(responseCount: 1);
105 });
106 socket.add('"blat"');
107 return result;
108 }
109
110 static Future notification() {
111 var result = client.notificationStream
112 .first
113 .timeout(new Duration(seconds: 1))
114 .then((Notification notification) {
115 expect(notification.event, equals('myEvent'));
116 expectMsgCount(notificationCount: 1);
117 expect(notificationsReceived.first, equals(notification));
118 });
119 server.sendNotification(new Notification('myEvent'));
120 return result;
121 }
122
123 static Future notificationAndResponse() {
124 var result = Future
125 .wait([
126 client.notificationStream.first,
127 client.responseStream.first])
128 .timeout(new Duration(seconds: 1))
129 .then((_) => expectMsgCount(responseCount: 1, notificationCount: 1));
130 server
131 ..sendNotification(new Notification('myEvent'))
132 ..sendResponse(new Response('myId'));
133 return result;
134 }
135
136 static void request() {
137 client.sendRequest(new Request('myId', 'myMth'));
138 server.listen((Request request) {
139 expect(request.id, equals('myId'));
140 expect(request.method, equals('myMth'));
141 expectMsgCount(requestCount: 1);
142 });
143 }
144
145 static Future requestResponse() {
146 // Simulate server sending a response by echoing the request.
147 server.listen((Request request) =>
148 server.sendResponse(new Response(request.id)));
149 return client.sendRequest(new Request('myId', 'myMth'))
150 .timeout(new Duration(seconds: 1))
151 .then((Response response) {
152 expect(response.id, equals('myId'));
153 expectMsgCount(requestCount: 1, responseCount: 1);
154
155 expect(requestsReceived.first is Request, isTrue);
156 Request request = requestsReceived.first;
157 expect(request.id, equals('myId'));
158 expect(request.method, equals('myMth'));
159 expect(responsesReceived.first, equals(response));
160 });
161 }
162
163 static Future response() {
164 server.sendResponse(new Response('myId'));
165 return client.responseStream
166 .first
167 .timeout(new Duration(seconds: 1))
168 .then((Response response) {
169 expect(response.id, equals('myId'));
170 expectMsgCount(responseCount: 1);
171 });
172 }
173
174 static void expectMsgCount({requestCount: 0,
175 responseCount: 0,
176 notificationCount: 0}) {
177 expect(requestsReceived, hasLength(requestCount));
178 expect(responsesReceived, hasLength(responseCount));
179 expect(notificationsReceived, hasLength(notificationCount));
180 }
181 }
182
183 class ByteStreamClientChannelTest {
184 static ByteStreamClientChannel channel;
185
186 /**
187 * Sink that may be used to deliver data to the channel, as though it's
188 * coming from the server.
189 */
190 static IOSink inputSink;
191
192 /**
193 * Sink through which the channel delivers data to the server.
194 */
195 static IOSink outputSink;
196
197 /**
198 * Stream of lines sent back to the client by the channel.
199 */
200 static Stream<String> outputLineStream;
201
202 static void setUp() {
203 var inputStream = new StreamController<List<int>>();
204 inputSink = new IOSink(inputStream);
205 var outputStream = new StreamController<List<int>>();
206 outputLineStream = outputStream.stream.transform((new Utf8Codec()).decoder
207 ).transform(new LineSplitter());
208 outputSink = new IOSink(outputStream);
209 channel = new ByteStreamClientChannel(inputStream.stream, outputSink);
210 }
211
212 static Future close() {
213 bool doneCalled = false;
214 bool closeCalled = false;
215 // add listener so that outputSink will trigger done/close futures
216 outputLineStream.listen((_) { /* no-op */ });
217 outputSink.done.then((_) {
218 doneCalled = true;
219 });
220 channel.close().then((_) {
221 closeCalled = true;
222 });
223 return pumpEventQueue().then((_) {
224 expect(doneCalled, isTrue);
225 expect(closeCalled, isTrue);
226 });
227 }
228
229 static Future listen_notification() {
230 List<Notification> notifications = [];
231 channel.notificationStream.forEach((n) => notifications.add(n));
232 inputSink.writeln('{"event":"server.connected"}');
233 return pumpEventQueue().then((_) {
234 expect(notifications.length, equals(1));
235 expect(notifications[0].event, equals('server.connected'));
236 });
237 }
238
239 static Future listen_response() {
240 List<Response> responses = [];
241 channel.responseStream.forEach((n) => responses.add(n));
242 inputSink.writeln('{"id":"72"}');
243 return pumpEventQueue().then((_) {
244 expect(responses.length, equals(1));
245 expect(responses[0].id, equals('72'));
246 });
247 }
248
249 static Future sendRequest() {
250 int assertCount = 0;
251 Request request = new Request('72', 'foo.bar');
252 outputLineStream.first
253 .then((line) => JSON.decode(line))
254 .then((json) {
255 expect(json[Request.ID], equals('72'));
256 expect(json[Request.METHOD], equals('foo.bar'));
257 inputSink.writeln('{"id":"73"}');
258 inputSink.writeln('{"id":"72"}');
259 assertCount++;
260 });
261 channel.sendRequest(request)
262 .then((Response response) {
263 expect(response.id, equals('72'));
264 assertCount++;
265 });
266 return pumpEventQueue().then((_) => expect(assertCount, equals(2)));
267 }
268 }
269
270 class ByteStreamServerChannelTest {
271 static ByteStreamServerChannel channel;
272
273 /**
274 * Sink that may be used to deliver data to the channel, as though it's
275 * coming from the client.
276 */
277 static IOSink inputSink;
278
279 /**
280 * Stream of lines sent back to the client by the channel.
281 */
282 static Stream<String> outputLineStream;
283
284 /**
285 * Stream of requests received from the channel via [listen()].
286 */
287 static Stream<Request> requestStream;
288
289 /**
290 * Stream of errors received from the channel via [listen()].
291 */
292 static Stream errorStream;
293
294 /**
295 * Future which is completed when then [listen()] reports [onDone].
296 */
297 static Future doneFuture;
298
299 static void setUp() {
300 StreamController<List<int>> inputStream = new StreamController<List<int>>();
301 inputSink = new IOSink(inputStream);
302 StreamController<List<int>> outputStream = new StreamController<List<int>>(
303 );
304 outputLineStream = outputStream.stream.transform((new Utf8Codec()).decoder
305 ).transform(new LineSplitter());
306 IOSink outputSink = new IOSink(outputStream);
307 channel = new ByteStreamServerChannel(inputStream.stream, outputSink);
308 StreamController<Request> requestStreamController =
309 new StreamController<Request>();
310 requestStream = requestStreamController.stream;
311 StreamController errorStreamController = new StreamController();
312 errorStream = errorStreamController.stream;
313 Completer doneCompleter = new Completer();
314 doneFuture = doneCompleter.future;
315 channel.listen((Request request) {
316 requestStreamController.add(request);
317 }, onError: (error) {
318 errorStreamController.add(error);
319 }, onDone: () {
320 doneCompleter.complete();
321 });
322 }
323
324 static Future closed() {
325 return inputSink.close().then((_) => channel.closed.timeout(new Duration(
326 seconds: 1)));
327 }
328
329 static Future listen_wellFormedRequest() {
330 inputSink.writeln('{"id":"0","method":"server.version"}');
331 return inputSink.flush().then((_) => requestStream.first.timeout(
332 new Duration(seconds: 1))).then((Request request) {
333 expect(request.id, equals("0"));
334 expect(request.method, equals("server.version"));
335 });
336 }
337
338 static Future listen_invalidRequest() {
339 inputSink.writeln('{"id":"0"}');
340 return inputSink.flush().then((_) => outputLineStream.first.timeout(
341 new Duration(seconds: 1))).then((String response) {
342 var jsonResponse = new JsonCodec().decode(response);
343 expect(jsonResponse, isMap);
344 expect(jsonResponse, contains('error'));
345 expect(jsonResponse['error'], isNotNull);
346 });
347 }
348
349 static Future listen_invalidJson() {
350 inputSink.writeln('{"id":');
351 return inputSink.flush().then((_) => outputLineStream.first.timeout(
352 new Duration(seconds: 1))).then((String response) {
353 var jsonResponse = new JsonCodec().decode(response);
354 expect(jsonResponse, isMap);
355 expect(jsonResponse, contains('error'));
356 expect(jsonResponse['error'], isNotNull);
357 });
358 }
359
360 static Future listen_streamError() {
361 var error = new Error();
362 inputSink.addError(error);
363 return inputSink.flush().then((_) => errorStream.first.timeout(new Duration(
364 seconds: 1))).then((var receivedError) {
365 expect(receivedError, same(error));
366 });
367 }
368
369 static Future listen_streamDone() {
370 return inputSink.close().then((_) => doneFuture.timeout(new Duration(
371 seconds: 1)));
372 }
373
374 static Future sendNotification() {
375 channel.sendNotification(new Notification('foo'));
376 return outputLineStream.first.timeout(new Duration(seconds: 1)).then((String
377 notification) {
378 var jsonNotification = new JsonCodec().decode(notification);
379 expect(jsonNotification, isMap);
380 expect(jsonNotification, contains('event'));
381 expect(jsonNotification['event'], equals('foo'));
382 });
383 }
384
385 static Future sendResponse() {
386 channel.sendResponse(new Response('foo'));
387 return outputLineStream.first.timeout(new Duration(seconds: 1)).then((String
388 response) {
389 var jsonResponse = new JsonCodec().decode(response);
390 expect(jsonResponse, isMap);
391 expect(jsonResponse, contains('id'));
392 expect(jsonResponse['id'], equals('foo'));
393 });
394 }
395 }
OLDNEW
« no previous file with comments | « pkg/analysis_server/test/channel/web_socket_channel_test.dart ('k') | pkg/analysis_server/test/mocks.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698