afcfbbeba8
(Part of https://github.com/dart-lang/sdk/issues/63288) This change migrates the packages owned by the developer experience team to use the new constructor declaration syntax, described in https://github.com/dart-lang/language/blob/main/accepted/future-releases/primary-constructors/feature-specification.md#abbreviations-of-in-body-constructor-declarations. This change was performed in an automated fashion, by (a) bumping the packages' SDK constraints to `3.13.0-0`, (b) enabling the lints `unnecessary_type_name_in_constructor` and `unnecessary_const_in_enum_constructor`, (c) fixing the resulting lint failures using `dart fix`, and then (d) reformatting the affected files. To ease code review, I've reverted unrelated formatting changes. Since this change requires bumping SDK constaints to `3.13.0-0`, it was only performed on packages that are *not* published on pub. (Packages that *are* published on pub should remain on lower language versions until at least after the stable version of 3.13 is released, so that we don't block users on the stable channel from receiving updates to those packages.) Change-Id: Ibb4daebafd239da58251e838ea6a3f336a6a6964 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/505046 Commit-Queue: Paul Berry <paulberry@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> SLSA-Policy-Verified: SLSA Policy Verification Service <devtools-gerritcodereview-exitgate@google.com>
284 lines
7.4 KiB
Dart
284 lines
7.4 KiB
Dart
// 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:analysis_server/src/plugin/notification_manager.dart';
|
|
import 'package:analysis_server/src/protocol_server.dart';
|
|
import 'package:analysis_server/src/utilities/process.dart';
|
|
import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
|
|
import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol;
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:test/test.dart';
|
|
|
|
/// A [Matcher] that check that the given [Response] has an expected identifier
|
|
/// and has an error. The error code may optionally be checked.
|
|
Matcher isResponseFailure(String id, [RequestErrorCode? code]) =>
|
|
_IsResponseFailure(id, code);
|
|
|
|
/// A [Matcher] that check that the given [Response] has an expected identifier
|
|
/// and no error.
|
|
Matcher isResponseSuccess(String id) => _IsResponseSuccess(id);
|
|
|
|
class MockHttpClient extends http.BaseClient {
|
|
late Future<http.Response> Function(http.BaseRequest request) sendHandler;
|
|
int sendHandlerCalls = 0;
|
|
bool wasClosed = false;
|
|
|
|
@override
|
|
void close() {
|
|
wasClosed = true;
|
|
}
|
|
|
|
@override
|
|
dynamic noSuchMethod(Invocation invocation) {
|
|
return super.noSuchMethod(invocation);
|
|
}
|
|
|
|
@override
|
|
Future<http.StreamedResponse> send(http.BaseRequest request) {
|
|
if (wasClosed) {
|
|
throw Exception('get() called after close()');
|
|
}
|
|
|
|
return sendHandler(request)
|
|
.then(
|
|
(resp) => http.StreamedResponse(
|
|
Stream.value(resp.body.codeUnits),
|
|
resp.statusCode,
|
|
),
|
|
)
|
|
.whenComplete(() => sendHandlerCalls++);
|
|
}
|
|
}
|
|
|
|
class MockProcess implements Process {
|
|
static int killedExitCode = -1;
|
|
|
|
final int _pid;
|
|
final _exitCodeCompleter = Completer<int>();
|
|
final String _stdout, _stderr;
|
|
|
|
new(this._pid, FutureOr<int> exitCode, this._stdout, this._stderr) {
|
|
Future.value(exitCode).then(_exitCodeCompleter.complete);
|
|
}
|
|
|
|
@override
|
|
Future<int> get exitCode => _exitCodeCompleter.future;
|
|
|
|
@override
|
|
int get pid => _pid;
|
|
|
|
@override
|
|
Stream<List<int>> get stderr => Stream<List<int>>.value(utf8.encode(_stderr));
|
|
|
|
@override
|
|
Stream<List<int>> get stdout => Stream<List<int>>.value(utf8.encode(_stdout));
|
|
|
|
@override
|
|
bool kill([ProcessSignal signal = ProcessSignal.sigterm]) {
|
|
_exitCodeCompleter.complete(killedExitCode);
|
|
return true;
|
|
}
|
|
|
|
@override
|
|
dynamic noSuchMethod(Invocation invocation) {
|
|
return super.noSuchMethod(invocation);
|
|
}
|
|
}
|
|
|
|
class MockProcessRunner implements ProcessRunner {
|
|
@override
|
|
final Map<String, String>? environment = null;
|
|
|
|
ProcessResult Function(
|
|
String executable,
|
|
List<String> arguments, {
|
|
String? workingDirectory,
|
|
Map<String, String>? environment,
|
|
Encoding? stderrEncoding,
|
|
Encoding? stdoutEncoding,
|
|
})
|
|
runSyncHandler =
|
|
(_, _, {workingDirectory, environment, stderrEncoding, stdoutEncoding}) =>
|
|
throw UnimplementedError();
|
|
|
|
FutureOr<Process> Function(
|
|
String executable,
|
|
List<String> arguments, {
|
|
String? workingDirectory,
|
|
Map<String, String>? environment,
|
|
})
|
|
startHandler = (_, _, {workingDirectory, environment}) =>
|
|
throw UnimplementedError();
|
|
|
|
@override
|
|
ProcessResult runSync(
|
|
String executable,
|
|
List<String> arguments, {
|
|
String? workingDirectory,
|
|
Map<String, String>? environment,
|
|
Encoding? stderrEncoding,
|
|
Encoding? stdoutEncoding,
|
|
}) => runSyncHandler(
|
|
executable,
|
|
arguments,
|
|
workingDirectory: workingDirectory,
|
|
environment: environment,
|
|
stderrEncoding: stderrEncoding,
|
|
stdoutEncoding: stdoutEncoding,
|
|
);
|
|
|
|
@override
|
|
Future<Process> start(
|
|
String executable,
|
|
List<String> arguments, {
|
|
String? workingDirectory,
|
|
Map<String, String>? environment,
|
|
bool includeParentEnvironment = true,
|
|
bool runInShell = false,
|
|
ProcessStartMode mode = ProcessStartMode.normal,
|
|
}) async {
|
|
return await startHandler(
|
|
executable,
|
|
arguments,
|
|
workingDirectory: workingDirectory,
|
|
environment: environment,
|
|
);
|
|
}
|
|
}
|
|
|
|
class TestNotificationManager implements AbstractNotificationManager {
|
|
List<plugin.Notification> notifications = [];
|
|
|
|
Map<String, Map<String, List<protocol.AnalysisError>>> recordedErrors = {};
|
|
|
|
List<String> pluginErrors = [];
|
|
|
|
@override
|
|
Stream<PluginPrint> pluginPrints = Stream.empty();
|
|
|
|
@override
|
|
void handlePluginError(String message) {
|
|
pluginErrors.add(message);
|
|
}
|
|
|
|
@override
|
|
void handlePluginNotification(
|
|
String pluginId,
|
|
plugin.Notification notification,
|
|
) {
|
|
notifications.add(notification);
|
|
}
|
|
|
|
@override
|
|
dynamic noSuchMethod(Invocation invocation) {
|
|
fail('Unexpected invocation of ${invocation.memberName}');
|
|
}
|
|
|
|
@override
|
|
void recordAnalysisErrors(
|
|
String pluginId,
|
|
String filePath,
|
|
List<protocol.AnalysisError> errorData,
|
|
) {
|
|
recordedErrors.putIfAbsent(pluginId, () => {})[filePath] = errorData;
|
|
}
|
|
}
|
|
|
|
/// A [Matcher] that check that there are no `error` in a given [Response].
|
|
class _IsResponseFailure extends Matcher {
|
|
final String _id;
|
|
final RequestErrorCode? _code;
|
|
|
|
new(this._id, this._code);
|
|
|
|
@override
|
|
Description describe(Description description) {
|
|
description = description.add(
|
|
'response with identifier "$_id" and an error',
|
|
);
|
|
var code = _code;
|
|
if (code != null) {
|
|
description = description.add(' with code ${code.name}');
|
|
}
|
|
return description;
|
|
}
|
|
|
|
@override
|
|
Description describeMismatch(
|
|
Object? item,
|
|
Description mismatchDescription,
|
|
Map<Object?, Object?> matchState,
|
|
bool verbose,
|
|
) {
|
|
var response = item as Response;
|
|
var id = response.id;
|
|
var error = response.error;
|
|
mismatchDescription.add('has identifier "$id"');
|
|
if (error == null) {
|
|
mismatchDescription.add(' and has no error');
|
|
} else {
|
|
mismatchDescription.add(' and has error code ${error.code.name}');
|
|
}
|
|
return mismatchDescription;
|
|
}
|
|
|
|
@override
|
|
bool matches(Object? item, Map<Object?, Object?> matchState) {
|
|
var response = item as Response;
|
|
var error = response.error;
|
|
if (response.id != _id || error == null) {
|
|
return false;
|
|
}
|
|
if (_code != null && error.code != _code) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// A [Matcher] that check that there are no `error` in a given [Response].
|
|
class _IsResponseSuccess extends Matcher {
|
|
final String _id;
|
|
|
|
new(this._id);
|
|
|
|
@override
|
|
Description describe(Description description) {
|
|
return description.addDescriptionOf(
|
|
'response with identifier "$_id" and without error',
|
|
);
|
|
}
|
|
|
|
@override
|
|
Description describeMismatch(
|
|
Object? item,
|
|
Description mismatchDescription,
|
|
Map<Object?, Object?> matchState,
|
|
bool verbose,
|
|
) {
|
|
var response = item as Response?;
|
|
if (response == null) {
|
|
mismatchDescription.add('is null response');
|
|
} else {
|
|
var id = response.id;
|
|
var error = response.error;
|
|
mismatchDescription.add('has identifier "$id"');
|
|
if (error != null) {
|
|
mismatchDescription.add(' and has error $error');
|
|
}
|
|
}
|
|
return mismatchDescription;
|
|
}
|
|
|
|
@override
|
|
bool matches(Object? item, Map<Object?, Object?> matchState) {
|
|
var response = item as Response?;
|
|
return response != null && response.id == _id && response.error == null;
|
|
}
|
|
}
|