blob: da7b2de36125e26bebba1f49f3ab7c1ebad76efc [file] [log] [blame]
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import 'dart:isolate';
import 'package:analyzer_plugin/protocol/protocol.dart';
import 'package:analyzer_plugin/protocol/protocol_generated.dart';
import 'package:analyzer_plugin/src/channel/isolate_channel.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
void main() {
defineReflectiveTests(PluginIsolateChannelTest);
}
@reflectiveTest
class PluginIsolateChannelTest {
TestSendPort sendPort;
PluginIsolateChannel channel;
void setUp() {
sendPort = new TestSendPort();
channel = new PluginIsolateChannel(sendPort);
}
void tearDown() {
// If the test doesn't listen to the channel, then close will not cancel the
// subscription and the process will not terminate.
try {
channel.listen((request) {});
} catch (exception) {
// Ignore the exception if the test has already registered a listener.
}
channel.close();
}
@failingTest
Future<void> test_close() async {
bool done = false;
channel.listen((Request request) {}, onDone: () {
done = true;
});
channel.close();
// TODO(brianwilkerson) Figure out how to wait until the handler has been
// called.
await _pumpEventQueue();
expect(done, isTrue);
}
Future<void> test_listen() async {
Request sentRequest = new PluginShutdownParams().toRequest('5');
Request receivedRequest;
channel.listen((Request request) {
receivedRequest = request;
});
sendPort.receivePort.send(sentRequest.toJson());
await _pumpEventQueue(1);
expect(receivedRequest, sentRequest);
}
void test_sendNotification() {
Notification notification =
new PluginErrorParams(false, '', '').toNotification();
channel.sendNotification(notification);
expect(sendPort.sentMessages, hasLength(1));
expect(sendPort.sentMessages[0], notification.toJson());
}
void test_sendResponse() {
Response response = new PluginShutdownResult().toResponse('3', 1);
channel.sendResponse(response);
expect(sendPort.sentMessages, hasLength(1));
expect(sendPort.sentMessages[0], response.toJson());
}
/**
* Returns a [Future] that completes after pumping the event queue [times]
* times. By default, this should pump the event queue enough times to allow
* any code to run, as long as it's not waiting on some external event.
*/
Future<void> _pumpEventQueue([int times = 5000]) {
if (times == 0) return new Future.value();
// We use a delayed future to allow microtask events to finish. The
// Future.value or Future() constructors use scheduleMicrotask themselves and
// would therefore not wait for microtask callbacks that are scheduled after
// invoking this method.
return new Future.delayed(Duration.zero, () => _pumpEventQueue(times - 1));
}
}
/**
* A send port used in tests.
*/
class TestSendPort implements SendPort {
/**
* The receive port used to receive messages from the server.
*/
SendPort receivePort;
/**
* The messages sent to the server.
*/
List<Object> sentMessages = <Object>[];
@override
void send(message) {
if (receivePort == null) {
if (message is SendPort) {
receivePort = message;
} else {
fail('Did not receive a receive port as the first communication.');
}
} else {
sentMessages.add(message);
}
}
}