blob: c8f7fb30d9eca0cb9d8aa2e90b4af89760f9a180 [file] [log] [blame]
// Copyright (c) 2024, 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:convert';
import 'dart:io';
import 'dart:isolate';
import 'package:dtd/dtd.dart';
import 'package:test/test.dart';
import 'utils.dart';
void main() {
late ToolingDaemonTestProcess toolingDaemonProcess;
/// Gets the URI for [filename] in the example folder.
Uri getExampleFileUri(String filename) {
// Use resolvePackageUriSync and not Platform.script so that this works
// when run through 'dart test'.
return Isolate.resolvePackageUriSync(
Uri.parse('package:dtd/'),
)!
.resolve('../example/$filename');
}
setUp(() async {
toolingDaemonProcess = ToolingDaemonTestProcess();
await toolingDaemonProcess.start();
});
tearDown(() async {
toolingDaemonProcess.kill();
});
test('stream example', () async {
final receiveACompleter = Completer<void>();
final receiveBCompleter = Completer<void>();
final streamProcess = await Process.start(
Platform.resolvedExecutable,
[
'run',
getExampleFileUri('dtd_stream_example.dart').toString(),
toolingDaemonProcess.uri.toString(),
],
);
final lines = <String>[];
streamProcess.handle(
stdoutLines: (line) {
print('streamProcess stdout: $line');
lines.add(line);
final json = jsonDecode(line) as Map<String, Object?>;
if (json['step'] == 'Event A received') {
receiveACompleter.complete();
} else if (json['step'] == 'Event B received') {
receiveBCompleter.complete();
}
},
stderrLines: (line) => stderr.write('streamProcess stderr: $line'),
);
await streamProcess.exitCode;
expect(
lines,
containsAll([
'{"step":"Event A received","event":{"event":1}}',
'{"step":"Event B received","event":{"event":1}}',
]),
);
});
test('service example', () async {
final serviceExampleProcess = await Process.start(
Platform.resolvedExecutable,
[
'run',
getExampleFileUri('dtd_service_example.dart').toString(),
toolingDaemonProcess.uri.toString(),
],
);
final stdoutMessages = <Map<String, Object?>>[];
serviceExampleProcess.handle(
stdoutLines: (line) {
print('serviceExample stdout: $line');
stdoutMessages.add(jsonDecode(line) as Map<String, Object?>);
},
stderrLines: (line) => stderr.write('serviceExample stderr: $line'),
);
await serviceExampleProcess.exitCode;
expect(
stdoutMessages,
containsAll([
{
'stream': CoreDtdServiceConstants.servicesStreamId,
'kind': CoreDtdServiceConstants.serviceRegisteredKind,
'data': {
'service': 'ExampleServer',
'method': 'getServerState',
'capabilities': {'supportsNewExamples': true},
},
},
{
'type': 'ExampleStateResponse',
'status': 'The server is running',
'uptime': const Duration(minutes: 45).inMilliseconds,
},
{
'stream': CoreDtdServiceConstants.servicesStreamId,
'kind': CoreDtdServiceConstants.serviceUnregisteredKind,
'data': {
'service': 'ExampleServer',
'method': 'getServerState',
},
},
]),
);
});
test('file system example', () async {
final readCompleter = Completer<void>();
final listDirCompleter = Completer<void>();
final tmpDirectory = await Directory.systemTemp.createTemp();
DartToolingDaemon? client;
try {
client = await DartToolingDaemon.connect(
toolingDaemonProcess.uri,
);
await client.setIDEWorkspaceRoots(
toolingDaemonProcess.trustedSecret!,
[tmpDirectory.uri],
);
final fileSystemServiceExampleProcess = await Process.start(
Platform.resolvedExecutable,
[
'run',
getExampleFileUri('dtd_file_system_service_example.dart').toString(),
toolingDaemonProcess.uri.toString(),
tmpDirectory.uri.toString(),
],
);
final lines = <String>[];
fileSystemServiceExampleProcess.handle(
stdoutLines: (line) {
print('fileSystemServiceProcess stdout: $line');
lines.add(line);
final json = jsonDecode(line) as Map<String, Object?>;
if (json['step'] == 'read') {
readCompleter.complete();
} else if (json['step'] == 'listDirectories') {
listDirCompleter.complete();
}
},
stderrLines: (line) =>
stderr.write('fileSystemServiceProcess stderr: $line'),
);
await readCompleter.future;
await listDirCompleter.future;
expect(
lines,
containsAll(
[
jsonEncode({
'step': 'read',
'response': {
'type': 'FileContent',
'content': 'Here are some file contents to write.',
},
}),
jsonEncode({
'step': 'listDirectories',
'response': {
'type': 'UriList',
'uris': ['${tmpDirectory.uri.toString()}a.txt'],
},
}),
],
),
);
} finally {
await tmpDirectory.delete(recursive: true);
await client?.close();
}
});
}