blob: e573c47fd83b649319ff6a7211f503b04b61c036 [file] [log] [blame]
// Copyright (c) 2014, 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 'package:angel3_mock_request/angel3_mock_request.dart';
import 'package:dart_services/src/common.dart';
import 'package:dart_services/src/common_server_api.dart';
import 'package:dart_services/src/common_server_impl.dart';
import 'package:dart_services/src/protos/dart_services.pb.dart' as proto;
import 'package:dart_services/src/sdk.dart';
import 'package:dart_services/src/server_cache.dart';
import 'package:logging/logging.dart';
import 'package:protobuf/protobuf.dart';
import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:test/test.dart';
const preFormattedCode = r'''
void main()
{
int i = 0;
}
''';
const postFormattedCode = r'''
void main() {
int i = 0;
}
''';
const formatBadCode = r'''
void main()
{
print('foo')
}
''';
void main() => defineTests();
void defineTests() {
late CommonServerApi commonServerApi;
late CommonServerImpl commonServerImpl;
Future<MockHttpResponse> sendPostRequest(
String path,
GeneratedMessage? message,
) async {
final uri = Uri.parse('/api/$path');
final request = MockHttpRequest('POST', uri);
request.headers.add('content-type', jsonContentType);
if (message != null) {
request.add(utf8.encode(json.encode(message.toProto3Json())));
}
await request.close();
await shelf_io.handleRequest(request, commonServerApi.router.call);
return request.response;
}
Future<MockHttpResponse> sendGetRequest(
String path,
) async {
final uri = Uri.parse('/api/$path');
final request = MockHttpRequest('GET', uri);
request.headers.add('content-type', jsonContentType);
await request.close();
await shelf_io.handleRequest(request, commonServerApi.router.call);
return request.response;
}
group('CommonServerProto JSON', () {
final sdk =
Sdk.create(Platform.environment['FLUTTER_CHANNEL'] ?? stableChannel);
setUpAll(() async {
final cache = MockCache();
commonServerImpl = CommonServerImpl(cache, sdk);
commonServerApi = CommonServerApi(commonServerImpl);
await commonServerImpl.init();
// Some piece of initialization doesn't always happen fast enough for this
// request to work in time for the test. So try it here until the server
// returns something valid.
// TODO(jcollins-g): determine which piece of initialization isn't
// happening and deal with that in warmup/init.
{
var decodedJson = <dynamic, dynamic>{};
final jsonData = proto.SourceRequest()..source = sampleCodeError;
while (decodedJson.isEmpty) {
final response =
await sendPostRequest('dartservices/v2/analyze', jsonData);
expect(response.statusCode, 200);
expect(response.headers['content-type'],
['application/json; charset=utf-8']);
final data = await response.transform(utf8.decoder).join();
decodedJson = json.decode(data) as Map<dynamic, dynamic>;
}
}
});
tearDownAll(() async {
await commonServerImpl.shutdown();
});
setUp(() {
log.onRecord.listen((LogRecord rec) {
print('${rec.level.name}: ${rec.time}: ${rec.message}');
});
});
tearDown(log.clearListeners);
test('analyze Dart', () async {
final request = proto.SourceRequest()..source = sampleCode;
final response =
await sendPostRequest('dartservices/v2/analyze', request);
expect(response.statusCode, 200);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.AnalysisResults()..mergeFromProto3Json(data);
expect(reply.issues, isEmpty);
expect(reply.packageImports, isEmpty);
});
test('analyze Flutter', () async {
final request = proto.SourceRequest()..source = sampleCodeFlutter;
final response =
await sendPostRequest('dartservices/v2/analyze', request);
expect(response.statusCode, 200);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.AnalysisResults()..mergeFromProto3Json(data);
expect(reply.issues, isEmpty);
expect(reply.packageImports, ['flutter']);
});
test('analyze errors', () async {
final request = proto.SourceRequest()..source = sampleCodeError;
late proto.AnalysisResults reply;
final response =
await sendPostRequest('dartservices/v2/analyze', request);
expect(response.statusCode, 200);
expect(response.headers['content-type'],
['application/json; charset=utf-8']);
final data = json.decode(await response.transform(utf8.decoder).join());
reply = proto.AnalysisResults()..mergeFromProto3Json(data);
expect(reply.issues, hasLength(1));
expect(reply.issues[0].kind, 'error');
expect(reply.issues[0].line, 2);
expect(reply.issues[0].sourceName, 'main.dart');
expect(reply.issues[0].message, "Expected to find ';'.");
expect(reply.issues[0].hasFixes, true);
expect(reply.issues[0].charStart, 29);
expect(reply.issues[0].charLength, 1);
});
test('analyze negative-test noSource', () async {
final request = proto.SourceRequest();
final response =
await sendPostRequest('dartservices/v2/analyze', request);
expect(response.statusCode, 400);
});
test('compile', () async {
final request = proto.CompileRequest()..source = sampleCode;
final response =
await sendPostRequest('dartservices/v2/compile', request);
expect(response.statusCode, 200);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.CompileResponse()..mergeFromProto3Json(data);
expect(reply.result, isNotEmpty);
});
test('compile error', () async {
final request = proto.CompileRequest()..source = sampleCodeError;
final response =
await sendPostRequest('dartservices/v2/compile', request);
expect(response.statusCode, 400);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.CompileResponse()..mergeFromProto3Json(data);
expect(reply.error.message, contains('Error: Expected'));
});
test('compile negative-test noSource', () async {
final request = proto.CompileRequest();
final response =
await sendPostRequest('dartservices/v2/compile', request);
expect(response.statusCode, 400);
});
test('compileDDC', () async {
final request = proto.CompileRequest()..source = sampleCode;
final response =
await sendPostRequest('dartservices/v2/compileDDC', request);
expect(response.statusCode, 200);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.CompileDDCResponse()..mergeFromProto3Json(data);
expect(reply.result, isNotEmpty);
});
test('complete', () async {
final request = proto.SourceRequest()
..source = 'void main() {print("foo");}'
..offset = 1;
final response =
await sendPostRequest('dartservices/v2/complete', request);
expect(response.statusCode, 200);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.CompleteResponse()..mergeFromProto3Json(data);
expect(reply.completions, isNotEmpty);
});
test('complete no data', () async {
final request = await sendPostRequest(
'dartservices/v2/complete', proto.SourceRequest());
expect(request.statusCode, 400);
});
test('complete param missing', () async {
final request = proto.SourceRequest()..offset = 1;
final response =
await sendPostRequest('dartservices/v2/complete', request);
expect(response.statusCode, 400);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.CompleteResponse()..mergeFromProto3Json(data);
expect(reply.error.message, 'Missing parameter: \'source\'');
});
test('complete param missing 2', () async {
final request = proto.SourceRequest()
..source = 'void main() {print("foo");}';
final response =
await sendPostRequest('dartservices/v2/complete', request);
expect(response.statusCode, 400);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.CompleteResponse()..mergeFromProto3Json(data);
expect(reply.error.message, 'Missing parameter: \'offset\'');
});
test('document', () async {
final request = proto.SourceRequest()
..source = 'void main() {print("foo");}'
..offset = 17;
final response =
await sendPostRequest('dartservices/v2/document', request);
expect(response.statusCode, 200);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.DocumentResponse()..mergeFromProto3Json(data);
expect(reply.info, isNotEmpty);
});
test('document little data', () async {
final request = proto.SourceRequest()
..source = 'void main() {print("foo");}'
..offset = 2;
final response =
await sendPostRequest('dartservices/v2/document', request);
expect(response.statusCode, 200);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.DocumentResponse()..mergeFromProto3Json(data);
expect(reply.info, isEmpty);
});
test('document no data', () async {
final request = proto.SourceRequest()
..source = 'void main() {print("foo");}'
..offset = 12;
final response =
await sendPostRequest('dartservices/v2/document', request);
expect(response.statusCode, 200);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.DocumentResponse()..mergeFromProto3Json(data);
expect(reply.info, isEmpty);
});
test('document negative-test noSource', () async {
final request = proto.SourceRequest()..offset = 12;
final response =
await sendPostRequest('dartservices/v2/document', request);
expect(response.statusCode, 400);
});
test('document negative-test noOffset', () async {
final request = proto.SourceRequest()
..source = 'void main() {print("foo");}';
final response =
await sendPostRequest('dartservices/v2/document', request);
expect(response.statusCode, 400);
});
test('format', () async {
final request = proto.SourceRequest()..source = preFormattedCode;
final response = await sendPostRequest('dartservices/v2/format', request);
expect(response.statusCode, 200);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.FormatResponse()..mergeFromProto3Json(data);
expect(reply.newString, postFormattedCode);
});
test('format bad code', () async {
final request = proto.SourceRequest()..source = formatBadCode;
final response = await sendPostRequest('dartservices/v2/format', request);
expect(response.statusCode, 200);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.FormatResponse()..mergeFromProto3Json(data);
expect(reply.newString, formatBadCode);
});
test('format position', () async {
final request = proto.SourceRequest()
..source = preFormattedCode
..offset = 21;
final response = await sendPostRequest('dartservices/v2/format', request);
expect(response.statusCode, 200);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.FormatResponse()..mergeFromProto3Json(data);
expect(reply.newString, postFormattedCode);
expect(reply.offset, 24);
});
test('fix', () async {
final quickFixesCode = '''
import 'dart:async';
void main() {
int i = 0;
}
''';
final request = proto.SourceRequest()
..source = quickFixesCode
..offset = 10;
final response = await sendPostRequest('dartservices/v2/fixes', request);
expect(response.statusCode, 200);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.FixesResponse()..mergeFromProto3Json(data);
final fixes = reply.fixes;
expect(fixes.length, 1);
final problemAndFix = fixes[0];
expect(problemAndFix.problemMessage, isNotNull);
});
test('fixes completeness', () async {
final request = proto.SourceRequest()
..source = '''
void main() {
for (int i = 0; i < 4; i++) {
print('hello \$i')
}
}
'''
..offset = 67;
final response = await sendPostRequest('dartservices/v2/fixes', request);
expect(response.statusCode, 200);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.FixesResponse()..mergeFromProto3Json(data);
expect(reply.fixes[0].fixes[0].message, "Insert ';'");
expect(reply.fixes[0].fixes[0].edits[0].offset, 67);
expect(reply.fixes[0].fixes[0].edits[0].length, 0);
expect(reply.fixes[0].fixes[0].edits[0].replacement, ';');
expect(reply.fixes[0].problemMessage, "Expected to find ';'.");
expect(reply.fixes[0].offset, 66);
expect(reply.fixes[0].length, 1);
});
test('assist', () async {
final assistCode = '''
main() {
int v = 0;
}
''';
final request = proto.SourceRequest()
..source = assistCode
..offset = 15;
final response =
await sendPostRequest('dartservices/v2/assists', request);
expect(response.statusCode, 200);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.AssistsResponse()..mergeFromProto3Json(data);
final assists = reply.assists;
if (sdk.masterChannel || sdk.betaChannel) {
expect(assists, hasLength(3));
} else {
expect(assists, hasLength(2));
}
expect(assists.first.edits, isNotNull);
expect(assists.first.edits, hasLength(1));
expect(
assists.where((candidateFix) =>
candidateFix.message == 'Remove type annotation'),
isNotEmpty);
});
test('version', () async {
final response = await sendPostRequest('dartservices/v2/version', null);
expect(response.statusCode, 200);
final encoded = await response.transform(utf8.decoder).join();
final data = json.decode(encoded) as Map<String, dynamic>;
expect(data['sdkVersion'], isNotNull);
expect(data['runtimeVersion'], isNotNull);
});
test('version', () async {
final response = await sendGetRequest('dartservices/v2/version');
expect(response.statusCode, 200);
final encoded = await response.transform(utf8.decoder).join();
final data = json.decode(encoded) as Map<String, dynamic>;
expect(data['sdkVersion'], isNotNull);
expect(data['runtimeVersion'], isNotNull);
});
});
//-----------------------------------------------------------------
// Beginning of multi file files={} group tests:
group('CommonServerProto JSON Multi File Group files={}', () {
final sdk =
Sdk.create(Platform.environment['FLUTTER_CHANNEL'] ?? stableChannel);
setUpAll(() async {
final cache = MockCache();
commonServerImpl = CommonServerImpl(cache, sdk);
commonServerApi = CommonServerApi(commonServerImpl);
await commonServerImpl.init();
// Some piece of initialization doesn't always happen fast enough for this
// request to work in time for the test. So try it here until the server
// returns something valid.
// TODO(jcollins-g): determine which piece of initialization isn't
// happening and deal with that in warmup/init.
{
var decodedJson = <dynamic, dynamic>{};
final jsonData = proto.SourceRequest()..source = sampleCodeError;
while (decodedJson.isEmpty) {
final response =
await sendPostRequest('dartservices/v2/analyze', jsonData);
expect(response.statusCode, 200);
expect(response.headers['content-type'],
['application/json; charset=utf-8']);
final data = await response.transform(utf8.decoder).join();
decodedJson = json.decode(data) as Map<dynamic, dynamic>;
}
}
});
tearDownAll(() async {
await commonServerImpl.shutdown();
});
setUp(() {
log.onRecord.listen((LogRecord rec) {
print('${rec.level.name}: ${rec.time}: ${rec.message}');
});
});
tearDown(log.clearListeners);
test('analyzeFiles Dart files={}', () async {
final request = proto.SourceFilesRequest()
..files.addAll({kMainDart: sampleCode});
final response =
await sendPostRequest('dartservices/v2/analyzeFiles', request);
expect(response.statusCode, 200);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.AnalysisResults()..mergeFromProto3Json(data);
expect(reply.issues, isEmpty);
expect(reply.packageImports, isEmpty);
});
test('analyzeFiles Flutter files={}', () async {
final request = proto.SourceFilesRequest()
..files.addAll({kMainDart: sampleCodeFlutter});
final response =
await sendPostRequest('dartservices/v2/analyzeFiles', request);
expect(response.statusCode, 200);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.AnalysisResults()..mergeFromProto3Json(data);
expect(reply.issues, isEmpty);
expect(reply.packageImports, ['flutter']);
});
test('analyzeFiles errors files={}', () async {
final request = proto.SourceFilesRequest()
..files.addAll({kMainDart: sampleCodeError});
late proto.AnalysisResults reply;
final response =
await sendPostRequest('dartservices/v2/analyzeFiles', request);
expect(response.statusCode, 200);
expect(response.headers['content-type'],
['application/json; charset=utf-8']);
final data = json.decode(await response.transform(utf8.decoder).join());
reply = proto.AnalysisResults()..mergeFromProto3Json(data);
expect(reply.issues, hasLength(1));
expect(reply.issues[0].kind, 'error');
expect(reply.issues[0].line, 2);
expect(reply.issues[0].sourceName, 'main.dart');
expect(reply.issues[0].message, "Expected to find ';'.");
expect(reply.issues[0].hasFixes, true);
expect(reply.issues[0].charStart, 29);
expect(reply.issues[0].charLength, 1);
});
test('analyzeFiles negative-test noSource files={}', () async {
final request = proto.SourceFilesRequest();
final response =
await sendPostRequest('dartservices/v2/analyzeFiles', request);
expect(response.statusCode, 400);
});
test('compileFiles files={}', () async {
final request = proto.CompileFilesRequest()
..files.addAll({kMainDart: sampleCode});
final response =
await sendPostRequest('dartservices/v2/compileFiles', request);
expect(response.statusCode, 200);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.CompileResponse()..mergeFromProto3Json(data);
expect(reply.result, isNotEmpty);
});
test('compileFiles 2 simple import files set in files={}', () async {
final request = proto.CompileFilesRequest()
..files.addAll({
kMainDart: sampleCodeMultiFoo,
'bar.dart': sampleCodeMultiBar,
})
..returnSourceMap = false;
final response =
await sendPostRequest('dartservices/v2/compileFiles', request);
expect(response.statusCode, 200);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.CompileResponse()..mergeFromProto3Json(data);
expect(reply.result, isNotEmpty);
});
test('compileFiles error files={}', () async {
final request = proto.CompileFilesRequest()
..files.addAll({kMainDart: sampleCodeError});
final response =
await sendPostRequest('dartservices/v2/compileFiles', request);
expect(response.statusCode, 400);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.CompileResponse()..mergeFromProto3Json(data);
expect(reply.error.message, contains('Error: Expected'));
});
test('compileFiles negative-test noSource files={}', () async {
final request = proto.CompileFilesRequest();
final response =
await sendPostRequest('dartservices/v2/compileFiles', request);
expect(response.statusCode, 400);
});
test('compileFilesDDC mymain.dart files={}', () async {
final request = proto.CompileFilesDDCRequest()
..files.addAll({'mymain.dart': sampleCode});
final response =
await sendPostRequest('dartservices/v2/compileFilesDDC', request);
expect(response.statusCode, 200);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.CompileDDCResponse()..mergeFromProto3Json(data);
expect(reply.result, isNotEmpty);
});
test('compileFilesDDC 3 files set in files={}', () async {
final request = proto.CompileFilesDDCRequest()
..files.addAll({
kMainDart: sampleCode3PartLibraryMain,
'discdata.dart': sampleCode3PartDiscDataPartOfTestAnim,
'various.dart': sampleCode3PartVariousPartOfTestAnim
});
final response =
await sendPostRequest('dartservices/v2/compileFilesDDC', request);
expect(response.statusCode, 200);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.CompileDDCResponse()..mergeFromProto3Json(data);
expect(reply.result, isNotEmpty);
});
test('completeFiles files={}', () async {
final request = proto.SourceFilesRequest()
..files.addAll({kMainDart: 'void main() {print("foo");}'})
..activeSourceName = kMainDart
..offset = 1;
final response =
await sendPostRequest('dartservices/v2/completeFiles', request);
expect(response.statusCode, 200);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.CompleteResponse()..mergeFromProto3Json(data);
expect(reply.completions, isNotEmpty);
});
test('completeFiles no data files={}', () async {
final request = await sendPostRequest(
'dartservices/v2/completeFiles', proto.SourceFilesRequest());
expect(request.statusCode, 400);
});
test('completeFiles param missing files={}', () async {
final request = proto.SourceFilesRequest()..offset = 1;
final response =
await sendPostRequest('dartservices/v2/completeFiles', request);
expect(response.statusCode, 400);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.CompleteResponse()..mergeFromProto3Json(data);
expect(reply.error.message, 'Missing parameter: \'files\'');
});
test('completeFiles param missing 2 files={}', () async {
final request = proto.SourceFilesRequest()
..files.addAll({kMainDart: 'void main() {print("foo");}'});
final response =
await sendPostRequest('dartservices/v2/completeFiles', request);
expect(response.statusCode, 400);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.CompleteResponse()..mergeFromProto3Json(data);
expect(reply.error.message, 'Missing parameter: \'activeSourceName\'');
});
test('documentFiles files={}', () async {
final request = proto.SourceFilesRequest()
..files.addAll({kMainDart: 'void main() {print("foo");}'})
..activeSourceName = kMainDart
..offset = 17;
final response =
await sendPostRequest('dartservices/v2/documentFiles', request);
expect(response.statusCode, 200);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.DocumentResponse()..mergeFromProto3Json(data);
expect(reply.info, isNotEmpty);
});
test('documentFiles little data files={}', () async {
final request = proto.SourceFilesRequest()
..files.addAll({kMainDart: 'void main() {print("foo");}'})
..activeSourceName = kMainDart
..offset = 2;
final response =
await sendPostRequest('dartservices/v2/documentFiles', request);
expect(response.statusCode, 200);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.DocumentResponse()..mergeFromProto3Json(data);
expect(reply.info, isEmpty);
});
test('documentFiles no data files={}', () async {
final request = proto.SourceFilesRequest()
..files.addAll({kMainDart: 'void main() {print("foo");}'})
..activeSourceName = kMainDart
..offset = 12;
final response =
await sendPostRequest('dartservices/v2/documentFiles', request);
expect(response.statusCode, 200);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.DocumentResponse()..mergeFromProto3Json(data);
expect(reply.info, isEmpty);
});
test('documentFiles negative-test noSource files={}', () async {
final request = proto.SourceFilesRequest()..offset = 12;
final response =
await sendPostRequest('dartservices/v2/documentFiles', request);
expect(response.statusCode, 400);
});
test('documentFiles negative-test noActiveSource noOffset files={}',
() async {
final request = proto.SourceFilesRequest()
..files.addAll({kMainDart: 'void main() {print("foo");}'});
final response =
await sendPostRequest('dartservices/v2/documentFiles', request);
expect(response.statusCode, 400);
});
test('fix2 files={}', () async {
final quickFixesCode = '''
import 'dart:async';
void main() {
int i = 0;
}
''';
final request = proto.SourceFilesRequest()
..files.addAll({kMainDart: quickFixesCode})
..activeSourceName = kMainDart
..offset = 10;
final response =
await sendPostRequest('dartservices/v2/fixesFiles', request);
expect(response.statusCode, 200);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.FixesResponse()..mergeFromProto3Json(data);
final fixes = reply.fixes;
expect(fixes.length, 1);
final problemAndFix = fixes[0];
expect(problemAndFix.problemMessage, isNotNull);
});
test('fixesFiles completeness files={}', () async {
final request = proto.SourceFilesRequest()
..files.addAll({
kMainDart: '''
void main() {
for (int i = 0; i < 4; i++) {
print('hello \$i')
}
}
'''
})
..activeSourceName = kMainDart
..offset = 67;
final response =
await sendPostRequest('dartservices/v2/fixesFiles', request);
expect(response.statusCode, 200);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.FixesResponse()..mergeFromProto3Json(data);
expect(reply.fixes[0].fixes[0].message, "Insert ';'");
expect(reply.fixes[0].fixes[0].edits[0].offset, 67);
expect(reply.fixes[0].fixes[0].edits[0].length, 0);
expect(reply.fixes[0].fixes[0].edits[0].replacement, ';');
expect(reply.fixes[0].problemMessage, "Expected to find ';'.");
expect(reply.fixes[0].offset, 66);
expect(reply.fixes[0].length, 1);
});
test('assist2 files={}', () async {
final assistCode = '''
main() {
int v = 0;
}
''';
final request = proto.SourceFilesRequest()
..files.addAll({kMainDart: assistCode})
..activeSourceName = kMainDart
..offset = 15;
final response =
await sendPostRequest('dartservices/v2/assistsFiles', request);
expect(response.statusCode, 200);
final data = json.decode(await response.transform(utf8.decoder).join());
final reply = proto.AssistsResponse()..mergeFromProto3Json(data);
final assists = reply.assists;
if (sdk.masterChannel || sdk.betaChannel) {
expect(assists, hasLength(3));
} else {
expect(assists, hasLength(2));
}
expect(assists.first.edits, isNotNull);
expect(assists.first.edits, hasLength(1));
expect(
assists.where((candidateFix) =>
candidateFix.message == 'Remove type annotation'),
isNotEmpty);
});
});
// End of multi file files={} tests group.
}
class MockCache implements ServerCache {
@override
Future<String?> get(String key) => Future.value(null);
@override
Future<void> set(String key, String value, {Duration? expiration}) =>
Future.value();
@override
Future<void> remove(String key) => Future.value();
@override
Future<void> shutdown() => Future.value();
}