Enable and fix pedantic v1.9 lints (#445)

Co-authored-by: Vyacheslav Egorov <vegorov@google.com>
This commit is contained in:
Kevin Moore 2021-02-01 00:12:26 -08:00 committed by GitHub
parent cbec527ba7
commit 32fbc03c63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
47 changed files with 215 additions and 129 deletions

View File

@ -28,18 +28,17 @@ jobs:
run: dart pub get run: dart pub get
- name: Check formatting - name: Check formatting
run: dart format --output=none --set-exit-if-changed . run: dart format --output=none --set-exit-if-changed .
- name: Analyze code (lib and test)
run: dart analyze --fatal-infos .
- name: Analyze code (introp and examples) - name: Analyze code (introp and examples)
run: | run: |
for example in interop example/*/; do for example in interop example/*/; do
pushd $example pushd $example
echo [Analyzing $example] echo [Getting dependencies in $example]
dart pub get dart pub get
dart analyze --fatal-infos .
popd popd
done done
shell: bash shell: bash
- name: Analyze code
run: dart analyze --fatal-infos .
# Run tests on a matrix consisting of three dimensions: # Run tests on a matrix consisting of three dimensions:
# 1. OS: mac, windows, linux # 1. OS: mac, windows, linux

View File

@ -1,21 +1,56 @@
# Lint rules and documentation, see http://dart-lang.github.io/linter/lints # Lint rules and documentation, see http://dart-lang.github.io/linter/lints
analyzer:
exclude:
- example/**
- interop/**
linter: linter:
rules: rules:
- always_declare_return_types
- always_require_non_null_named_parameters
- annotate_overrides
- avoid_empty_else
- avoid_init_to_null - avoid_init_to_null
- avoid_null_checks_in_equality_operators
- avoid_relative_lib_imports
- avoid_return_types_on_setters
- avoid_shadowing_type_parameters
- avoid_types_as_parameter_names
- camel_case_extensions
- cancel_subscriptions - cancel_subscriptions
- close_sinks - close_sinks
- curly_braces_in_flow_control_structures
- directives_ordering - directives_ordering
- empty_catches
- empty_constructor_bodies
- hash_and_equals - hash_and_equals
- iterable_contains_unrelated_type - iterable_contains_unrelated_type
- library_names
- library_prefixes
- list_remove_unrelated_type - list_remove_unrelated_type
- no_duplicate_case_values
- null_closures
- omit_local_variable_types
- prefer_adjacent_string_concatenation
- prefer_collection_literals
- prefer_conditional_assignment
- prefer_contains
- prefer_equal_for_default_values
- prefer_final_fields - prefer_final_fields
- prefer_final_locals - prefer_final_locals
- prefer_for_elements_to_map_fromIterable
- prefer_generic_function_type_aliases
- prefer_if_null_operators
- prefer_is_empty
- prefer_is_not_empty - prefer_is_not_empty
- prefer_iterable_whereType
- prefer_single_quotes
- prefer_spread_collections
- recursive_getters
- slash_for_doc_comments
- test_types_in_equals - test_types_in_equals
- type_init_formals
- unnecessary_const
- unnecessary_new
- unnecessary_null_in_if_null_operators
- unnecessary_this
- unrelated_type_equality_checks - unrelated_type_equality_checks
- use_function_type_syntax_for_parameters
- use_rethrow_when_possible
- valid_regexps - valid_regexps
- prefer_collection_literals

View File

@ -33,11 +33,11 @@ class EchoApp {
} }
void _addLeftMessage(String message) { void _addLeftMessage(String message) {
_addMessage(message, "label-primary pull-left"); _addMessage(message, 'label-primary pull-left');
} }
void _addRightMessage(String message) { void _addRightMessage(String message) {
_addMessage(message, "label-default pull-right"); _addMessage(message, 'label-default pull-right');
} }
void _addMessage(String message, String cssClass) { void _addMessage(String message, String cssClass) {

View File

@ -15,6 +15,6 @@
import 'package:metadata/src/client.dart'; import 'package:metadata/src/client.dart';
main(List<String> args) { void main(List<String> args) {
Client().main(args); Client().main(args);
} }

View File

@ -15,6 +15,6 @@
import 'package:metadata/src/server.dart'; import 'package:metadata/src/server.dart';
main(List<String> args) { void main(List<String> args) {
Server().main(args); Server().main(args);
} }

View File

@ -113,7 +113,7 @@ class Client {
/// after receiving more than 5 responses. /// after receiving more than 5 responses.
Future<void> runFibonacciCancel() async { Future<void> runFibonacciCancel() async {
final call = stub.fibonacci(Empty()); final call = stub.fibonacci(Empty());
int count = 0; var count = 0;
try { try {
await for (var number in call) { await for (var number in call) {
count++; count++;
@ -135,7 +135,7 @@ class Client {
Future<void> runFibonacciTimeout() async { Future<void> runFibonacciTimeout() async {
final call = stub.fibonacci(Empty(), final call = stub.fibonacci(Empty(),
options: CallOptions(timeout: Duration(seconds: 2))); options: CallOptions(timeout: Duration(seconds: 2)));
int count = 0; var count = 0;
try { try {
await for (var number in call) { await for (var number in call) {
count++; count++;

View File

@ -40,7 +40,7 @@ class MetadataService extends MetadataServiceBase {
@override @override
Stream<Number> addOne(grpc.ServiceCall call, Stream<Number> request) async* { Stream<Number> addOne(grpc.ServiceCall call, Stream<Number> request) async* {
int lastNumber = -1; var lastNumber = -1;
try { try {
await for (var number in request) { await for (var number in request) {
lastNumber = number.value; lastNumber = number.value;
@ -56,9 +56,10 @@ class MetadataService extends MetadataServiceBase {
} }
/// Streams a Fibonacci number every 500ms until the call is canceled. /// Streams a Fibonacci number every 500ms until the call is canceled.
@override
Stream<Number> fibonacci(grpc.ServiceCall call, Empty request) async* { Stream<Number> fibonacci(grpc.ServiceCall call, Empty request) async* {
int previous = 0; var previous = 0;
int current = 1; var current = 1;
try { try {
while (true) { while (true) {
await Future.delayed(Duration(milliseconds: 500)); await Future.delayed(Duration(milliseconds: 500));

View File

@ -15,6 +15,6 @@
import 'package:route_guide/src/client.dart'; import 'package:route_guide/src/client.dart';
main(List<String> args) async { Future<void> main(List<String> args) async {
await Client().main(args); await Client().main(args);
} }

View File

@ -15,6 +15,6 @@
import 'package:route_guide/src/server.dart'; import 'package:route_guide/src/server.dart';
main(List<String> args) async { Future<void> main(List<String> args) async {
await Server().main(args); await Server().main(args);
} }

View File

@ -94,7 +94,7 @@ class Client {
Stream<Point> generateRoute(int count) async* { Stream<Point> generateRoute(int count) async* {
final random = Random(); final random = Random();
for (int i = 0; i < count; i++) { for (var i = 0; i < count; i++) {
final point = featuresDb[random.nextInt(featuresDb.length)].location; final point = featuresDb[random.nextInt(featuresDb.length)].location;
print( print(
'Visiting point ${point.latitude / coordFactor}, ${point.longitude / coordFactor}'); 'Visiting point ${point.latitude / coordFactor}, ${point.longitude / coordFactor}');

View File

@ -75,9 +75,9 @@ class RouteGuideService extends RouteGuideServiceBase {
@override @override
Future<RouteSummary> recordRoute( Future<RouteSummary> recordRoute(
grpc.ServiceCall call, Stream<Point> request) async { grpc.ServiceCall call, Stream<Point> request) async {
int pointCount = 0; var pointCount = 0;
int featureCount = 0; var featureCount = 0;
double distance = 0.0; var distance = 0.0;
Point previous; Point previous;
final timer = Stopwatch(); final timer = Stopwatch();
@ -110,7 +110,9 @@ class RouteGuideService extends RouteGuideServiceBase {
grpc.ServiceCall call, Stream<RouteNote> request) async* { grpc.ServiceCall call, Stream<RouteNote> request) async* {
await for (var note in request) { await for (var note in request) {
final notes = routeNotes.putIfAbsent(note.location, () => <RouteNote>[]); final notes = routeNotes.putIfAbsent(note.location, () => <RouteNote>[]);
for (var note in notes) yield note; for (var note in notes) {
yield note;
}
notes.add(note); notes.add(note);
} }
} }

View File

@ -51,7 +51,7 @@ class Tester {
return File(serviceAccountKeyFile).readAsStringSync(); return File(serviceAccountKeyFile).readAsStringSync();
} }
void set serverPort(String value) { set serverPort(String value) {
if (value == null) { if (value == null) {
_serverPort = null; _serverPort = null;
return; return;
@ -63,11 +63,11 @@ class Tester {
} }
} }
void set useTls(String value) { set useTls(String value) {
_useTls = value != 'false'; _useTls = value != 'false';
} }
void set useTestCA(String value) { set useTestCA(String value) {
_useTestCA = value == 'true'; _useTestCA = value == 'true';
} }
@ -613,7 +613,7 @@ class Tester {
final call = client.fullDuplexCall(requests.stream); final call = client.fullDuplexCall(requests.stream);
requests.close(); requests.close();
final responses = await call.toList(); final responses = await call.toList();
if (responses.length != 0) { if (responses.isNotEmpty) {
throw 'Received too many responses. ${responses.length} != 0'; throw 'Received too many responses. ${responses.length} != 0';
} }
} }

View File

@ -60,6 +60,7 @@ abstract class BaseAuthenticator {
abstract class HttpBasedAuthenticator extends BaseAuthenticator { abstract class HttpBasedAuthenticator extends BaseAuthenticator {
Future<void>? _call; Future<void>? _call;
@override
Future<void> obtainAccessCredentials(String uri) { Future<void> obtainAccessCredentials(String uri) {
if (_call == null) { if (_call == null) {
final authClient = http.Client(); final authClient = http.Client();
@ -94,6 +95,7 @@ class JwtServiceAccountAuthenticator extends BaseAuthenticator {
String? get projectId => _projectId; String? get projectId => _projectId;
@override
Future<void> obtainAccessCredentials(String uri) async { Future<void> obtainAccessCredentials(String uri) async {
_accessToken = _jwtTokenFor(_serviceAccountCredentials, _keyId, uri); _accessToken = _jwtTokenFor(_serviceAccountCredentials, _keyId, uri);
} }

View File

@ -7,6 +7,7 @@ import 'package:http/http.dart' as http;
import 'auth.dart'; import 'auth.dart';
class ComputeEngineAuthenticator extends HttpBasedAuthenticator { class ComputeEngineAuthenticator extends HttpBasedAuthenticator {
@override
Future<auth.AccessCredentials> obtainCredentialsWithClient( Future<auth.AccessCredentials> obtainCredentialsWithClient(
http.Client client, String uri) => http.Client client, String uri) =>
auth.obtainAccessCredentialsViaMetadataServer(client); auth.obtainAccessCredentialsViaMetadataServer(client);
@ -30,6 +31,7 @@ class ServiceAccountAuthenticator extends HttpBasedAuthenticator {
String? get projectId => _projectId; String? get projectId => _projectId;
@override
Future<auth.AccessCredentials> obtainCredentialsWithClient( Future<auth.AccessCredentials> obtainCredentialsWithClient(
http.Client client, String uri) => http.Client client, String uri) =>
auth.obtainAccessCredentialsViaServiceAccount( auth.obtainAccessCredentialsViaServiceAccount(
@ -47,6 +49,7 @@ class _CredentialsRefreshingAuthenticator extends HttpBasedAuthenticator {
this._quotaProject, this._quotaProject,
); );
@override
Future<void> authenticate(Map<String, String> metadata, String uri) async { Future<void> authenticate(Map<String, String> metadata, String uri) async {
await super.authenticate(metadata, uri); await super.authenticate(metadata, uri);
if (_quotaProject != null) { if (_quotaProject != null) {

View File

@ -30,7 +30,7 @@ class RS256Signer {
// NIST sha-256 OID (2 16 840 1 101 3 4 2 1) // NIST sha-256 OID (2 16 840 1 101 3 4 2 1)
// See a reference for the encoding here: // See a reference for the encoding here:
// http://msdn.microsoft.com/en-us/library/bb540809%28v=vs.85%29.aspx // http://msdn.microsoft.com/en-us/library/bb540809%28v=vs.85%29.aspx
static const _RSA_SHA256_ALGORITHM_IDENTIFIER = const [ static const _RSA_SHA256_ALGORITHM_IDENTIFIER = [
0x06, 0x06,
0x09, 0x09,
0x60, 0x60,
@ -52,7 +52,7 @@ class RS256Signer {
final digest = _digestInfo(sha256.convert(bytes).bytes); final digest = _digestInfo(sha256.convert(bytes).bytes);
final modulusLen = (_rsaKey.bitLength + 7) ~/ 8; final modulusLen = (_rsaKey.bitLength + 7) ~/ 8;
final block = new Uint8List(modulusLen); final block = Uint8List(modulusLen);
final padLength = block.length - digest.length - 3; final padLength = block.length - digest.length - 3;
block[0] = 0x00; block[0] = 0x00;
block[1] = 0x01; block[1] = 0x01;
@ -68,7 +68,7 @@ class RS256Signer {
// digest OCTET STRING // digest OCTET STRING
// } // }
var offset = 0; var offset = 0;
final digestInfo = new Uint8List( final digestInfo = Uint8List(
2 + 2 + _RSA_SHA256_ALGORITHM_IDENTIFIER.length + 2 + 2 + hash.length); 2 + 2 + _RSA_SHA256_ALGORITHM_IDENTIFIER.length + 2 + 2 + hash.length);
{ {
// DigestInfo // DigestInfo
@ -100,14 +100,14 @@ class ASN1Parser {
static ASN1Object parse(Uint8List bytes) { static ASN1Object parse(Uint8List bytes) {
Never invalidFormat(String msg) { Never invalidFormat(String msg) {
throw new ArgumentError("Invalid DER encoding: $msg"); throw ArgumentError('Invalid DER encoding: $msg');
} }
final data = new ByteData.view(bytes.buffer); final data = ByteData.view(bytes.buffer);
int offset = 0; var offset = 0;
final end = bytes.length; final end = bytes.length;
checkNBytesAvailable(int n) { void checkNBytesAvailable(int n) {
if ((offset + n) > end) { if ((offset + n) > end) {
invalidFormat('Tried to read more bytes than available.'); invalidFormat('Tried to read more bytes than available.');
} }
@ -134,10 +134,10 @@ class ASN1Parser {
// Long length encoding form: // Long length encoding form:
// This byte has in bits 0..6 the number of bytes following which encode // This byte has in bits 0..6 the number of bytes following which encode
// the length. // the length.
int countLengthBytes = lengthByte & 0x7f; var countLengthBytes = lengthByte & 0x7f;
checkNBytesAvailable(countLengthBytes); checkNBytesAvailable(countLengthBytes);
int length = 0; var length = 0;
while (countLengthBytes > 0) { while (countLengthBytes > 0) {
length = (length << 8) | data.getUint8(offset++); length = (length << 8) | data.getUint8(offset++);
countLengthBytes--; countLengthBytes--;
@ -159,16 +159,16 @@ class ASN1Parser {
switch (tag) { switch (tag) {
case INTEGER_TAG: case INTEGER_TAG:
final size = readEncodedLength(); final size = readEncodedLength();
return new ASN1Integer(RSAAlgorithm.bytes2BigInt(readBytes(size))); return ASN1Integer(RSAAlgorithm.bytes2BigInt(readBytes(size)));
case OCTET_STRING_TAG: case OCTET_STRING_TAG:
final size = readEncodedLength(); final size = readEncodedLength();
return new ASN1OctetString(readBytes(size)); return ASN1OctetString(readBytes(size));
case NULL_TAG: case NULL_TAG:
readNullBytes(); readNullBytes();
return new ASN1Null(); return ASN1Null();
case OBJECT_ID_TAG: case OBJECT_ID_TAG:
final size = readEncodedLength(); final size = readEncodedLength();
return new ASN1ObjectIdentifier(readBytes(size)); return ASN1ObjectIdentifier(readBytes(size));
case SEQUENCE_TAG: case SEQUENCE_TAG:
final lengthInBytes = readEncodedLength(); final lengthInBytes = readEncodedLength();
if ((offset + lengthInBytes) > end) { if ((offset + lengthInBytes) > end) {
@ -180,7 +180,7 @@ class ASN1Parser {
while (offset < endOfSequence) { while (offset < endOfSequence) {
objects.add(decodeObject()); objects.add(decodeObject());
} }
return new ASN1Sequence(objects); return ASN1Sequence(objects);
default: default:
invalidFormat( invalidFormat(
'Unexpected tag $tag at offset ${offset - 1} (end: $end).'); 'Unexpected tag $tag at offset ${offset - 1} (end: $end).');
@ -189,7 +189,7 @@ class ASN1Parser {
final obj = decodeObject(); final obj = decodeObject();
if (offset != bytes.length) { if (offset != bytes.length) {
throw new ArgumentError('More bytes than expected in ASN1 encoding.'); throw ArgumentError('More bytes than expected in ASN1 encoding.');
} }
return obj; return obj;
} }
@ -300,17 +300,17 @@ abstract class RSAAlgorithm {
static BigInt bytes2BigInt(List<int> bytes) { static BigInt bytes2BigInt(List<int> bytes) {
var number = BigInt.zero; var number = BigInt.zero;
for (var i = 0; i < bytes.length; i++) { for (var i = 0; i < bytes.length; i++) {
number = (number << 8) | new BigInt.from(bytes[i]); number = (number << 8) | BigInt.from(bytes[i]);
} }
return number; return number;
} }
static List<int> integer2Bytes(BigInt integer, int intendedLength) { static List<int> integer2Bytes(BigInt integer, int intendedLength) {
if (integer < BigInt.one) { if (integer < BigInt.one) {
throw new ArgumentError('Only positive integers are supported.'); throw ArgumentError('Only positive integers are supported.');
} }
final bytes = new Uint8List(intendedLength); final bytes = Uint8List(intendedLength);
for (int i = bytes.length - 1; i >= 0; i--) { for (var i = bytes.length - 1; i >= 0; i--) {
bytes[i] = (integer & _bigIntFF).toInt(); bytes[i] = (integer & _bigIntFF).toInt();
integer >>= 8; integer >>= 8;
} }
@ -318,4 +318,4 @@ abstract class RSAAlgorithm {
} }
} }
final _bigIntFF = new BigInt.from(0xff); final _bigIntFF = BigInt.from(0xff);

View File

@ -50,7 +50,7 @@ const _statusDetailsHeader = 'grpc-status-details-bin';
/// by previous metadata providers) and the [uri] that is being called, and is /// by previous metadata providers) and the [uri] that is being called, and is
/// expected to modify the map before returning or before completing the /// expected to modify the map before returning or before completing the
/// returned [Future]. /// returned [Future].
typedef FutureOr<void> MetadataProvider( typedef MetadataProvider = FutureOr<void> Function(
Map<String, String> metadata, String uri); Map<String, String> metadata, String uri);
/// Runtime options for an RPC. /// Runtime options for an RPC.

View File

@ -45,9 +45,8 @@ regenerate these stubs using protobuf compiler plugin version 19.2.0 or newer.
ResponseFuture<R> $createUnaryCall<Q, R>(ClientMethod<Q, R> method, Q request, ResponseFuture<R> $createUnaryCall<Q, R>(ClientMethod<Q, R> method, Q request,
{CallOptions? options}) { {CallOptions? options}) {
ClientUnaryInvoker<Q, R> invoker = (method, request, options) => var invoker = (method, request, options) => ResponseFuture<R>(
ResponseFuture<R>( _channel.createCall<Q, R>(method, Stream.value(request), options));
_channel.createCall<Q, R>(method, Stream.value(request), options));
for (final interceptor in _interceptors.reversed) { for (final interceptor in _interceptors.reversed) {
final delegate = invoker; final delegate = invoker;
@ -61,7 +60,7 @@ regenerate these stubs using protobuf compiler plugin version 19.2.0 or newer.
ResponseStream<R> $createStreamingCall<Q, R>( ResponseStream<R> $createStreamingCall<Q, R>(
ClientMethod<Q, R> method, Stream<Q> requests, ClientMethod<Q, R> method, Stream<Q> requests,
{CallOptions? options}) { {CallOptions? options}) {
ClientStreamingInvoker<Q, R> invoker = (method, request, options) => var invoker = (method, request, options) =>
ResponseStream<R>(_channel.createCall<Q, R>(method, requests, options)); ResponseStream<R>(_channel.createCall<Q, R>(method, requests, options));
for (final interceptor in _interceptors.reversed) { for (final interceptor in _interceptors.reversed) {

View File

@ -44,6 +44,7 @@ abstract class Response {
/// A gRPC response producing a single value. /// A gRPC response producing a single value.
class ResponseFuture<R> extends DelegatingFuture<R> class ResponseFuture<R> extends DelegatingFuture<R>
with _ResponseMixin<dynamic, R> { with _ResponseMixin<dynamic, R> {
@override
final ClientCall<dynamic, R> _call; final ClientCall<dynamic, R> _call;
static R _ensureOnlyOneResponse<R>(R? previous, R element) { static R _ensureOnlyOneResponse<R>(R? previous, R element) {
@ -67,11 +68,13 @@ class ResponseFuture<R> extends DelegatingFuture<R>
/// A gRPC response producing a stream of values. /// A gRPC response producing a stream of values.
class ResponseStream<R> extends DelegatingStream<R> class ResponseStream<R> extends DelegatingStream<R>
with _ResponseMixin<dynamic, R> { with _ResponseMixin<dynamic, R> {
@override
final ClientCall<dynamic, R> _call; final ClientCall<dynamic, R> _call;
ResponseStream(this._call) : super(_call.response); ResponseStream(this._call) : super(_call.response);
ResponseFuture<R> get single => ResponseFuture(this._call); @override
ResponseFuture<R> get single => ResponseFuture(_call);
} }
abstract class _ResponseMixin<Q, R> implements Response { abstract class _ResponseMixin<Q, R> implements Response {

View File

@ -66,13 +66,15 @@ class Http2ClientConnection implements connection.ClientConnection {
ChannelCredentials get credentials => options.credentials; ChannelCredentials get credentials => options.credentials;
@override
String get authority => _transportConnector.authority; String get authority => _transportConnector.authority;
@override
String get scheme => options.credentials.isSecure ? 'https' : 'http'; String get scheme => options.credentials.isSecure ? 'https' : 'http';
ConnectionState get state => _state; ConnectionState get state => _state;
static const _estimatedRoundTripTime = const Duration(milliseconds: 20); static const _estimatedRoundTripTime = Duration(milliseconds: 20);
Future<ClientTransportConnection> connectTransport() async { Future<ClientTransportConnection> connectTransport() async {
final connection = await _transportConnector.connect(); final connection = await _transportConnector.connect();
@ -81,7 +83,7 @@ class Http2ClientConnection implements connection.ClientConnection {
// Give the settings settings-frame a bit of time to arrive. // Give the settings settings-frame a bit of time to arrive.
// TODO(sigurdm): This is a hack. The http2 package should expose a way of // TODO(sigurdm): This is a hack. The http2 package should expose a way of
// waiting for the settings frame to arrive. // waiting for the settings frame to arrive.
await new Future.delayed(_estimatedRoundTripTime); await Future.delayed(_estimatedRoundTripTime);
if (_state == ConnectionState.shutdown) { if (_state == ConnectionState.shutdown) {
_transportConnector.shutdown(); _transportConnector.shutdown();
@ -119,8 +121,8 @@ class Http2ClientConnection implements connection.ClientConnection {
/// ///
/// Assumes [_transportConnection] is not `null`. /// Assumes [_transportConnection] is not `null`.
void _refreshConnectionIfUnhealthy() { void _refreshConnectionIfUnhealthy() {
final bool isHealthy = _transportConnection!.isOpen; final isHealthy = _transportConnection!.isOpen;
final bool shouldRefresh = final shouldRefresh =
_connectionLifeTimer.elapsed > options.connectionTimeout; _connectionLifeTimer.elapsed > options.connectionTimeout;
if (shouldRefresh) { if (shouldRefresh) {
_transportConnection!.finish(); _transportConnection!.finish();
@ -130,6 +132,7 @@ class Http2ClientConnection implements connection.ClientConnection {
} }
} }
@override
void dispatchCall(ClientCall call) { void dispatchCall(ClientCall call) {
if (_transportConnection != null) { if (_transportConnection != null) {
_refreshConnectionIfUnhealthy(); _refreshConnectionIfUnhealthy();
@ -149,6 +152,7 @@ class Http2ClientConnection implements connection.ClientConnection {
} }
} }
@override
GrpcTransportStream makeRequest(String path, Duration? timeout, GrpcTransportStream makeRequest(String path, Duration? timeout,
Map<String, String> metadata, ErrorHandler onRequestFailure, Map<String, String> metadata, ErrorHandler onRequestFailure,
{CallOptions? callOptions}) { {CallOptions? callOptions}) {
@ -188,12 +192,14 @@ class Http2ClientConnection implements connection.ClientConnection {
_failCall(call, 'Connection shutting down.'); _failCall(call, 'Connection shutting down.');
} }
@override
Future<void> shutdown() async { Future<void> shutdown() async {
if (_state == ConnectionState.shutdown) return null; if (_state == ConnectionState.shutdown) return null;
_setShutdownState(); _setShutdownState();
await _transportConnection?.finish(); await _transportConnection?.finish();
} }
@override
Future<void> terminate() async { Future<void> terminate() async {
_setShutdownState(); _setShutdownState();
await _transportConnection?.terminate(); await _transportConnection?.terminate();
@ -353,7 +359,7 @@ class _SocketTransportConnector implements ClientTransportConnector {
final host = final host =
_host is String ? _host as String : (_host as InternetAddress).host; _host is String ? _host as String : (_host as InternetAddress).host;
return _options.credentials.authority ?? return _options.credentials.authority ??
(_port == 443 ? host : "$host:$_port"); (_port == 443 ? host : '$host:$_port');
} }
@override @override

View File

@ -26,7 +26,7 @@ const defaultIdleTimeout = Duration(minutes: 5);
const defaultConnectionTimeOut = Duration(minutes: 50); const defaultConnectionTimeOut = Duration(minutes: 50);
const defaultUserAgent = 'dart-grpc/2.0.0'; const defaultUserAgent = 'dart-grpc/2.0.0';
typedef Duration BackoffStrategy(Duration? lastBackoff); typedef BackoffStrategy = Duration Function(Duration? lastBackoff);
// Backoff algorithm from https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md // Backoff algorithm from https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md
const _initialBackoff = Duration(seconds: 1); const _initialBackoff = Duration(seconds: 1);

View File

@ -21,7 +21,8 @@ import '../../shared/security.dart';
/// returns `true`, the bad certificate is allowed, and the TLS handshake can /// returns `true`, the bad certificate is allowed, and the TLS handshake can
/// continue. If the handler returns `false`, the TLS handshake fails, and the /// continue. If the handler returns `false`, the TLS handshake fails, and the
/// connection is aborted. /// connection is aborted.
typedef bool BadCertificateHandler(X509Certificate certificate, String host); typedef BadCertificateHandler = bool Function(
X509Certificate certificate, String host);
/// Bad certificate handler that disables all certificate checks. /// Bad certificate handler that disables all certificate checks.
/// DO NOT USE IN PRODUCTION! /// DO NOT USE IN PRODUCTION!
@ -60,7 +61,7 @@ class ChannelCredentials {
..setTrustedCertificatesBytes(_certificateBytes!, ..setTrustedCertificatesBytes(_certificateBytes!,
password: _certificatePassword); password: _certificatePassword);
} }
final context = new SecurityContext(withTrustedRoots: true); final context = SecurityContext(withTrustedRoots: true);
context.setAlpnProtocols(supportedAlpnProtocols, false); context.setAlpnProtocols(supportedAlpnProtocols, false);
return context; return context;
} }

View File

@ -25,10 +25,12 @@ import 'transport.dart';
class Http2TransportStream extends GrpcTransportStream { class Http2TransportStream extends GrpcTransportStream {
final TransportStream _transportStream; final TransportStream _transportStream;
@override
final Stream<GrpcMessage> incomingMessages; final Stream<GrpcMessage> incomingMessages;
final StreamController<List<int>> _outgoingMessages = StreamController(); final StreamController<List<int>> _outgoingMessages = StreamController();
final ErrorHandler _onError; final ErrorHandler _onError;
@override
StreamSink<List<int>> get outgoingMessages => _outgoingMessages.sink; StreamSink<List<int>> get outgoingMessages => _outgoingMessages.sink;
Http2TransportStream( Http2TransportStream(

View File

@ -17,12 +17,13 @@ import 'dart:async';
import '../../shared/message.dart'; import '../../shared/message.dart';
typedef void SocketClosedHandler(); typedef SocketClosedHandler = void Function();
typedef void ActiveStateHandler(bool isActive); typedef ActiveStateHandler = void Function(bool isActive);
typedef void ErrorHandler(error, StackTrace stackTrace); typedef ErrorHandler = void Function(Object, StackTrace);
abstract class GrpcTransportStream { abstract class GrpcTransportStream {
Stream<GrpcMessage> get incomingMessages; Stream<GrpcMessage> get incomingMessages;
StreamSink<List<int>> get outgoingMessages; StreamSink<List<int>> get outgoingMessages;
Future<void> terminate(); Future<void> terminate();

View File

@ -166,7 +166,9 @@ class XhrClientConnection extends ClientConnection {
XhrClientConnection(this.uri); XhrClientConnection(this.uri);
@override
String get authority => uri.authority; String get authority => uri.authority;
@override
String get scheme => uri.scheme; String get scheme => uri.scheme;
void _initializeRequest(HttpRequest request, Map<String, String> metadata) { void _initializeRequest(HttpRequest request, Map<String, String> metadata) {
@ -198,7 +200,7 @@ class XhrClientConnection extends ClientConnection {
requestUri = cors.moveHttpHeadersToQueryParam(metadata, requestUri); requestUri = cors.moveHttpHeadersToQueryParam(metadata, requestUri);
} }
final HttpRequest request = createHttpRequest(); final request = createHttpRequest();
request.open('POST', requestUri.toString()); request.open('POST', requestUri.toString());
if (callOptions is WebCallOptions && callOptions.withCredentials == true) { if (callOptions is WebCallOptions && callOptions.withCredentials == true) {
request.withCredentials = true; request.withCredentials = true;
@ -206,7 +208,7 @@ class XhrClientConnection extends ClientConnection {
// Must set headers after calling open(). // Must set headers after calling open().
_initializeRequest(request, metadata); _initializeRequest(request, metadata);
final XhrTransportStream transportStream = final transportStream =
XhrTransportStream(request, onError: onError, onDone: _removeStream); XhrTransportStream(request, onError: onError, onDone: _removeStream);
_requests.add(transportStream); _requests.add(transportStream);
return transportStream; return transportStream;

View File

@ -66,16 +66,22 @@ class ServerHandler_ extends ServiceCall {
this._codecRegistry, this._codecRegistry,
); );
@override
DateTime? get deadline => _deadline; DateTime? get deadline => _deadline;
@override
bool get isCanceled => _isCanceled; bool get isCanceled => _isCanceled;
@override
bool get isTimedOut => _isTimedOut; bool get isTimedOut => _isTimedOut;
@override
Map<String, String>? get clientMetadata => _clientMetadata; Map<String, String>? get clientMetadata => _clientMetadata;
@override
Map<String, String>? get headers => _customHeaders; Map<String, String>? get headers => _customHeaders;
@override
Map<String, String>? get trailers => _customTrailers; Map<String, String>? get trailers => _customTrailers;
void handle() { void handle() {
@ -162,7 +168,7 @@ class ServerHandler_ extends ServiceCall {
Future<GrpcError?> _applyInterceptors() async { Future<GrpcError?> _applyInterceptors() async {
try { try {
for (final interceptor in _interceptors) { for (final interceptor in _interceptors) {
final error = await interceptor(this, this._descriptor); final error = await interceptor(this, _descriptor);
if (error != null) { if (error != null) {
return error; return error;
} }
@ -293,6 +299,7 @@ class ServerHandler_ extends ServiceCall {
} }
} }
@override
void sendHeaders() { void sendHeaders() {
if (_headersSent) throw GrpcError.internal('Headers already sent'); if (_headersSent) throw GrpcError.internal('Headers already sent');
@ -316,6 +323,7 @@ class ServerHandler_ extends ServiceCall {
_headersSent = true; _headersSent = true;
} }
@override
void sendTrailers({int? status = 0, String? message}) { void sendTrailers({int? status = 0, String? message}) {
_timeoutTimer?.cancel(); _timeoutTimer?.cancel();
@ -336,7 +344,7 @@ class ServerHandler_ extends ServiceCall {
outgoingTrailersMap['grpc-status'] = status.toString(); outgoingTrailersMap['grpc-status'] = status.toString();
if (message != null) { if (message != null) {
outgoingTrailersMap['grpc-message'] = outgoingTrailersMap['grpc-message'] =
Uri.encodeFull(message).replaceAll("%20", " "); Uri.encodeFull(message).replaceAll('%20', ' ');
} }
final outgoingTrailers = <Header>[]; final outgoingTrailers = <Header>[];

View File

@ -61,6 +61,7 @@ class ServerTlsCredentials extends ServerCredentials {
this.privateKey, this.privateKey,
this.privateKeyPassword}); this.privateKeyPassword});
@override
SecurityContext get securityContext { SecurityContext get securityContext {
final context = createSecurityContext(true); final context = createSecurityContext(true);
if (privateKey != null) { if (privateKey != null) {
@ -152,6 +153,7 @@ class Server extends ConnectionServer {
return null; return null;
} }
@override
Service? lookupService(String service) => _services[service]; Service? lookupService(String service) => _services[service];
/// Starts the [Server] with the given options. /// Starts the [Server] with the given options.
@ -162,9 +164,9 @@ class Server extends ConnectionServer {
int? port, int? port,
ServerCredentials? security, ServerCredentials? security,
ServerSettings? http2ServerSettings, ServerSettings? http2ServerSettings,
int backlog: 0, int backlog = 0,
bool v6Only: false, bool v6Only = false,
bool shared: false}) async { bool shared = false}) async {
// TODO(dart-lang/grpc-dart#9): Handle HTTP/1.1 upgrade to h2c, if allowed. // TODO(dart-lang/grpc-dart#9): Handle HTTP/1.1 upgrade to h2c, if allowed.
Stream<Socket>? server; Stream<Socket>? server;
final securityContext = security?.securityContext; final securityContext = security?.securityContext;
@ -198,6 +200,7 @@ class Server extends ConnectionServer {
}); });
} }
@override
@visibleForTesting @visibleForTesting
ServerHandler_ serveStream_(ServerTransportStream stream) { ServerHandler_ serveStream_(ServerTransportStream stream) {
return ServerHandler_(lookupService, stream, _interceptors, _codecRegistry) return ServerHandler_(lookupService, stream, _interceptors, _codecRegistry)

View File

@ -84,7 +84,7 @@ class ServiceMethod<Q, R> {
return future; return future;
} }
void _awaitAndCatch<Q>(Future<Q> f) async { void _awaitAndCatch(Future<Q> f) async {
try { try {
await f; await f;
} catch (_) {} } catch (_) {}

View File

@ -54,7 +54,7 @@ class GzipCodec implements Codec {
const GzipCodec(); const GzipCodec();
@override @override
final encodingName = "gzip"; final encodingName = 'gzip';
@override @override
List<int> compress(List<int> data) { List<int> compress(List<int> data) {

View File

@ -15,7 +15,7 @@
import 'dart:developer'; import 'dart:developer';
typedef TimelineTask TimelineTaskFactory( typedef TimelineTaskFactory = TimelineTask Function(
{String? filterKey, TimelineTask? parent}); {String? filterKey, TimelineTask? parent});
TimelineTaskFactory timelineTaskFactory = _defaultTimelineTaskFactory; TimelineTaskFactory timelineTaskFactory = _defaultTimelineTaskFactory;

View File

@ -23,6 +23,7 @@ class TestClient extends grpc.Client {
} }
class TestService extends grpc.Service { class TestService extends grpc.Service {
@override
String get $name => 'test.TestService'; String get $name => 'test.TestService';
TestService() { TestService() {
@ -47,11 +48,11 @@ class FixedConnectionClientChannel extends ClientChannelBase {
ClientConnection createConnection() => clientConnection; ClientConnection createConnection() => clientConnection;
} }
main() async { Future<void> main() async {
testTcpAndUds('client reconnects after the connection gets old', testTcpAndUds('client reconnects after the connection gets old',
(address) async { (address) async {
// client reconnect after a short delay. // client reconnect after a short delay.
final grpc.Server server = grpc.Server([TestService()]); final server = grpc.Server([TestService()]);
await server.serve(address: address, port: 0); await server.serve(address: address, port: 0);
final channel = FixedConnectionClientChannel(Http2ClientConnection( final channel = FixedConnectionClientChannel(Http2ClientConnection(
@ -76,7 +77,7 @@ main() async {
testTcpAndUds('client reconnects when stream limit is used', (address) async { testTcpAndUds('client reconnects when stream limit is used', (address) async {
// client reconnect after setting stream limit. // client reconnect after setting stream limit.
final grpc.Server server = grpc.Server([TestService()]); final server = grpc.Server([TestService()]);
await server.serve( await server.serve(
address: address, address: address,
port: 0, port: 0,

View File

@ -5,7 +5,7 @@ void main() {
test('WebCallOptions mergeWith CallOptions returns WebCallOptions', () { test('WebCallOptions mergeWith CallOptions returns WebCallOptions', () {
final options = final options =
WebCallOptions(bypassCorsPreflight: true, withCredentials: true); WebCallOptions(bypassCorsPreflight: true, withCredentials: true);
final metadata = {"test": "42"}; final metadata = {'test': '42'};
final mergedOptions = final mergedOptions =
options.mergedWith(CallOptions(metadata: metadata)) as WebCallOptions; options.mergedWith(CallOptions(metadata: metadata)) as WebCallOptions;

View File

@ -13,6 +13,7 @@ class InterceptorInvocation {
InterceptorInvocation(this.id, this.unary, this.streaming); InterceptorInvocation(this.id, this.unary, this.streaming);
@override
String toString() { String toString() {
return '{id: ${id}, unary: ${unary}, streaming: ${streaming}}'; return '{id: ${id}, unary: ${unary}, streaming: ${streaming}}';
} }
@ -48,7 +49,7 @@ class FakeInterceptor implements ClientInterceptor {
CallOptions _inject(CallOptions options) { CallOptions _inject(CallOptions options) {
return options.mergedWith(CallOptions(metadata: { return options.mergedWith(CallOptions(metadata: {
"x-interceptor": _invocations.map((i) => i.toString()).join(', '), 'x-interceptor': _invocations.map((i) => i.toString()).join(', '),
})); }));
} }
@ -57,7 +58,7 @@ class FakeInterceptor implements ClientInterceptor {
} }
} }
main() { void main() {
test('single unary interceptor', () async { test('single unary interceptor', () async {
final harness = ClientHarness() final harness = ClientHarness()
..interceptors = [FakeInterceptor(1)] ..interceptors = [FakeInterceptor(1)]
@ -81,7 +82,7 @@ main() {
expectedResult: responseValue, expectedResult: responseValue,
expectedPath: '/Test/Unary', expectedPath: '/Test/Unary',
expectedCustomHeaders: { expectedCustomHeaders: {
"x-interceptor": "{id: 1, unary: 1, streaming: 0}" 'x-interceptor': '{id: 1, unary: 1, streaming: 0}'
}, },
serverHandlers: [handleRequest], serverHandlers: [handleRequest],
); );
@ -113,8 +114,8 @@ main() {
expectedResult: responseValue, expectedResult: responseValue,
expectedPath: '/Test/Unary', expectedPath: '/Test/Unary',
expectedCustomHeaders: { expectedCustomHeaders: {
"x-interceptor": 'x-interceptor':
"{id: 1, unary: 1, streaming: 0}, {id: 2, unary: 1, streaming: 0}" '{id: 1, unary: 1, streaming: 0}, {id: 2, unary: 1, streaming: 0}'
}, },
serverHandlers: [handleRequest], serverHandlers: [handleRequest],
); );
@ -154,7 +155,7 @@ main() {
expectedResult: responses, expectedResult: responses,
expectedPath: '/Test/Bidirectional', expectedPath: '/Test/Bidirectional',
expectedCustomHeaders: { expectedCustomHeaders: {
"x-interceptor": "{id: 1, unary: 0, streaming: 1}" 'x-interceptor': '{id: 1, unary: 0, streaming: 1}'
}, },
serverHandlers: [handleRequest, handleRequest, handleRequest], serverHandlers: [handleRequest, handleRequest, handleRequest],
doneHandler: handleDone, doneHandler: handleDone,
@ -195,8 +196,8 @@ main() {
expectedResult: responses, expectedResult: responses,
expectedPath: '/Test/Bidirectional', expectedPath: '/Test/Bidirectional',
expectedCustomHeaders: { expectedCustomHeaders: {
"x-interceptor": 'x-interceptor':
"{id: 1, unary: 0, streaming: 1}, {id: 2, unary: 0, streaming: 1}" '{id: 1, unary: 0, streaming: 1}, {id: 2, unary: 0, streaming: 1}'
}, },
serverHandlers: [handleRequest, handleRequest, handleRequest], serverHandlers: [handleRequest, handleRequest, handleRequest],
doneHandler: handleDone, doneHandler: handleDone,

View File

@ -330,7 +330,7 @@ void main() {
} }
harness.client = TestClient(harness.channel, decode: (bytes) { harness.client = TestClient(harness.channel, decode: (bytes) {
throw "error decoding"; throw 'error decoding';
}); });
await harness.runFailureTest( await harness.runFailureTest(
@ -439,9 +439,9 @@ void main() {
}); });
test('Default reconnect backoff backs off', () { test('Default reconnect backoff backs off', () {
Duration lastBackoff = defaultBackoffStrategy(null); var lastBackoff = defaultBackoffStrategy(null);
expect(lastBackoff, const Duration(seconds: 1)); expect(lastBackoff, const Duration(seconds: 1));
for (int i = 0; i < 12; i++) { for (var i = 0; i < 12; i++) {
final minNext = lastBackoff * (1.6 - 0.2); final minNext = lastBackoff * (1.6 - 0.2);
final maxNext = lastBackoff * (1.6 + 0.2); final maxNext = lastBackoff * (1.6 + 0.2);
lastBackoff = defaultBackoffStrategy(lastBackoff); lastBackoff = defaultBackoffStrategy(lastBackoff);

View File

@ -280,7 +280,7 @@ void main() {
} }
harness.client = TestClient(harness.channel, decode: (bytes) { harness.client = TestClient(harness.channel, decode: (bytes) {
throw "error decoding"; throw 'error decoding';
}); });
await harness.runFailureTest( await harness.runFailureTest(
@ -389,9 +389,9 @@ void main() {
}); });
test('Default reconnect backoff backs off', () { test('Default reconnect backoff backs off', () {
Duration lastBackoff = defaultBackoffStrategy(null); var lastBackoff = defaultBackoffStrategy(null);
expect(lastBackoff, const Duration(seconds: 1)); expect(lastBackoff, const Duration(seconds: 1));
for (int i = 0; i < 12; i++) { for (var i = 0; i < 12; i++) {
final minNext = lastBackoff * (1.6 - 0.2); final minNext = lastBackoff * (1.6 - 0.2);
final maxNext = lastBackoff * (1.6 + 0.2); final maxNext = lastBackoff * (1.6 + 0.2);
lastBackoff = defaultBackoffStrategy(lastBackoff); lastBackoff = defaultBackoffStrategy(lastBackoff);

View File

@ -53,6 +53,7 @@ class MockHttpRequest extends Mock implements HttpRequest {
@override @override
final int status; final int status;
@override
int get readyState => super.noSuchMethod(Invocation.getter(#readyState), -1); int get readyState => super.noSuchMethod(Invocation.getter(#readyState), -1);
@override @override
@ -69,7 +70,7 @@ class MockXhrClientConnection extends XhrClientConnection {
final int _statusCode; final int _statusCode;
@override @override
createHttpRequest() { HttpRequest createHttpRequest() {
final request = MockHttpRequest(code: _statusCode); final request = MockHttpRequest(code: _statusCode);
latestRequest = request; latestRequest = request;
return request; return request;
@ -360,9 +361,9 @@ void main() {
final errorReceived = Completer<void>(); final errorReceived = Completer<void>();
connection.makeRequest('test_path', Duration(seconds: 10), {}, (e, _) { connection.makeRequest('test_path', Duration(seconds: 10), {}, (e, _) {
errorReceived.complete(); errorReceived.complete();
errors.add(e); errors.add(e as GrpcError);
}); });
const errorDetails = "error details"; const errorDetails = 'error details';
when(connection.latestRequest.getResponseHeader('Content-Type')) when(connection.latestRequest.getResponseHeader('Content-Type'))
.thenReturn('application/grpc+proto'); .thenReturn('application/grpc+proto');
when(connection.latestRequest.responseHeaders).thenReturn({}); when(connection.latestRequest.responseHeaders).thenReturn({});

View File

@ -289,7 +289,7 @@ void main() {
} }
final Interceptor interceptor = (call, method) { final Interceptor interceptor = (call, method) {
if (method.name == "Unary") { if (method.name == 'Unary') {
return null; return null;
} }
return GrpcError.unauthenticated('Request is unauthenticated'); return GrpcError.unauthenticated('Request is unauthenticated');
@ -311,7 +311,7 @@ void main() {
group('returns error if interceptor blocks request', () { group('returns error if interceptor blocks request', () {
final Interceptor interceptor = (call, method) { final Interceptor interceptor = (call, method) {
if (method.name == "Unary") { if (method.name == 'Unary') {
return GrpcError.unauthenticated('Request is unauthenticated'); return GrpcError.unauthenticated('Request is unauthenticated');
} }
return null; return null;

View File

@ -5,9 +5,9 @@ import 'package:grpc/src/client/transport/web_streams.dart';
import 'package:grpc/src/shared/message.dart'; import 'package:grpc/src/shared/message.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
main() { void main() {
test("decoding an empty repeated", () async { test('decoding an empty repeated', () async {
final GrpcData data = await GrpcWebDecoder() final data = await GrpcWebDecoder()
.bind(Stream.fromIterable([ .bind(Stream.fromIterable([
Uint8List.fromList([0, 0, 0, 0, 0]).buffer Uint8List.fromList([0, 0, 0, 0, 0]).buffer
])) ]))

View File

@ -85,7 +85,7 @@ static_resources:
port_value: %TARGET_PORT% port_value: %TARGET_PORT%
'''; ''';
hybridMain(StreamChannel channel) async { Future<void> hybridMain(StreamChannel channel) async {
// Envoy output will be collected and dumped to stdout if envoy exits // Envoy output will be collected and dumped to stdout if envoy exits
// with an error. Otherwise if verbose is specified it will be dumped // with an error. Otherwise if verbose is specified it will be dumped
// to stdout unconditionally. // to stdout unconditionally.

View File

@ -56,7 +56,7 @@ void main() {
// Verify that terminate does not cause an exception when terminating // Verify that terminate does not cause an exception when terminating
// channel with multiple active requests. // channel with multiple active requests.
test("terminate works", () async { test('terminate works', () async {
final channel = GrpcWebClientChannel.xhr(server.uri); final channel = GrpcWebClientChannel.xhr(server.uri);
final service = EchoServiceClient(channel); final service = EchoServiceClient(channel);
@ -96,7 +96,7 @@ void main() {
}); });
// Verify that stream cancellation does not cause an exception // Verify that stream cancellation does not cause an exception
test("stream cancellation works", () async { test('stream cancellation works', () async {
final channel = GrpcWebClientChannel.xhr(server.uri); final channel = GrpcWebClientChannel.xhr(server.uri);
final service = EchoServiceClient(channel); final service = EchoServiceClient(channel);

View File

@ -23,6 +23,7 @@ class TestClient extends Client {
} }
class TestService extends Service { class TestService extends Service {
@override
String get $name => 'test.TestService'; String get $name => 'test.TestService';
TestService() { TestService() {
@ -43,6 +44,7 @@ class TestService extends Service {
} }
class TestServiceWithOnMetadataException extends TestService { class TestServiceWithOnMetadataException extends TestService {
@override
void $onMetadata(ServiceCall context) { void $onMetadata(ServiceCall context) {
throw Exception('business exception'); throw Exception('business exception');
} }
@ -58,10 +60,10 @@ class FixedConnectionClientChannel extends ClientChannelBase {
ClientConnection createConnection() => clientConnection; ClientConnection createConnection() => clientConnection;
} }
main() async { Future<void> main() async {
testTcpAndUds('round trip insecure connection', (address) async { testTcpAndUds('round trip insecure connection', (address) async {
// round trip test of insecure connection. // round trip test of insecure connection.
final Server server = Server([TestService()]); final server = Server([TestService()]);
await server.serve(address: address, port: 0); await server.serve(address: address, port: 0);
final channel = FixedConnectionClientChannel(Http2ClientConnection( final channel = FixedConnectionClientChannel(Http2ClientConnection(
@ -77,7 +79,7 @@ main() async {
testTcpAndUds('round trip with outgoing and incoming compression', testTcpAndUds('round trip with outgoing and incoming compression',
(address) async { (address) async {
final Server server = Server( final server = Server(
[TestService()], const [], CodecRegistry(codecs: const [GzipCodec()])); [TestService()], const [], CodecRegistry(codecs: const [GzipCodec()]));
await server.serve(address: address, port: 0); await server.serve(address: address, port: 0);
@ -101,7 +103,7 @@ main() async {
testTcpAndUds('round trip secure connection', (address) async { testTcpAndUds('round trip secure connection', (address) async {
// round trip test of secure connection. // round trip test of secure connection.
final Server server = Server([TestService()]); final server = Server([TestService()]);
await server.serve( await server.serve(
address: address, address: address,
port: 0, port: 0,
@ -124,7 +126,7 @@ main() async {
}); });
test('exception in onMetadataException', () async { test('exception in onMetadataException', () async {
final Server server = Server([TestServiceWithOnMetadataException()]); final server = Server([TestServiceWithOnMetadataException()]);
await server.serve(address: 'localhost', port: 0); await server.serve(address: 'localhost', port: 0);
final channel = FixedConnectionClientChannel(Http2ClientConnection( final channel = FixedConnectionClientChannel(Http2ClientConnection(
@ -140,7 +142,7 @@ main() async {
}); });
test('cancellation of streaming subscription propagates properly', () async { test('cancellation of streaming subscription propagates properly', () async {
final Server server = Server([TestService()]); final server = Server([TestService()]);
await server.serve(address: 'localhost', port: 0); await server.serve(address: 'localhost', port: 0);
final channel = FixedConnectionClientChannel(Http2ClientConnection( final channel = FixedConnectionClientChannel(Http2ClientConnection(

View File

@ -21,6 +21,7 @@ class TestClient extends grpc.Client {
} }
class TestService extends grpc.Service { class TestService extends grpc.Service {
@override
String get $name => 'test.TestService'; String get $name => 'test.TestService';
final void Function() finallyCallback; final void Function() finallyCallback;
@ -31,7 +32,7 @@ class TestService extends grpc.Service {
Stream<int> infiniteStream( Stream<int> infiniteStream(
grpc.ServiceCall call, Future<int> request) async* { grpc.ServiceCall call, Future<int> request) async* {
int count = await request; var count = await request;
try { try {
while (true) { while (true) {
count++; count++;
@ -70,9 +71,9 @@ void client(clientData) async {
}); });
} }
main() async { Future<void> main() async {
testTcpAndUds( testTcpAndUds(
"the client interrupting the connection does not crash the server", 'the client interrupting the connection does not crash the server',
(address) async { (address) async {
// interrrupt the connect of client, the server does not crash. // interrrupt the connect of client, the server does not crash.
late grpc.Server server; late grpc.Server server;

View File

@ -169,7 +169,7 @@ void main() {
test('Server returns encoded error for unary call', () async { test('Server returns encoded error for unary call', () async {
Future<int> methodHandler(ServiceCall call, Future<int> request) async { Future<int> methodHandler(ServiceCall call, Future<int> request) async {
throw GrpcError.unknown("エラー"); throw GrpcError.unknown('エラー');
} }
harness harness
@ -303,7 +303,7 @@ void main() {
} }
final Interceptor interceptor = (call, method) { final Interceptor interceptor = (call, method) {
if (method.name == "Unary") { if (method.name == 'Unary') {
return null; return null;
} }
return GrpcError.unauthenticated('Request is unauthenticated'); return GrpcError.unauthenticated('Request is unauthenticated');
@ -325,7 +325,7 @@ void main() {
group('returns error if interceptor blocks request', () { group('returns error if interceptor blocks request', () {
final Interceptor interceptor = (call, method) { final Interceptor interceptor = (call, method) {
if (method.name == "Unary") { if (method.name == 'Unary') {
return GrpcError.unauthenticated('Request is unauthenticated'); return GrpcError.unauthenticated('Request is unauthenticated');
} }
return null; return null;

View File

@ -62,16 +62,23 @@ class FakeClientTransportConnection extends Http2ClientConnection {
Duration testBackoff(Duration? lastBackoff) => const Duration(milliseconds: 1); Duration testBackoff(Duration? lastBackoff) => const Duration(milliseconds: 1);
class FakeChannelOptions implements ChannelOptions { class FakeChannelOptions implements ChannelOptions {
@override
ChannelCredentials credentials = const ChannelCredentials.secure(); ChannelCredentials credentials = const ChannelCredentials.secure();
@override
Duration idleTimeout = const Duration(seconds: 1); Duration idleTimeout = const Duration(seconds: 1);
@override
Duration connectionTimeout = const Duration(seconds: 10); Duration connectionTimeout = const Duration(seconds: 10);
@override
String userAgent = 'dart-grpc/1.0.0 test'; String userAgent = 'dart-grpc/1.0.0 test';
@override
BackoffStrategy backoffStrategy = testBackoff; BackoffStrategy backoffStrategy = testBackoff;
@override
CodecRegistry codecRegistry = CodecRegistry.empty(); CodecRegistry codecRegistry = CodecRegistry.empty();
} }
class FakeChannel extends ClientChannel { class FakeChannel extends ClientChannel {
final Http2ClientConnection connection; final Http2ClientConnection connection;
@override
final FakeChannelOptions options; final FakeChannelOptions options;
FakeChannel(String host, this.connection, this.options) FakeChannel(String host, this.connection, this.options)
@ -83,6 +90,7 @@ class FakeChannel extends ClientChannel {
class FakeClientConnectorChannel extends ClientTransportConnectorChannel { class FakeClientConnectorChannel extends ClientTransportConnectorChannel {
final Http2ClientConnection connection; final Http2ClientConnection connection;
@override
final FakeChannelOptions options; final FakeChannelOptions options;
FakeClientConnectorChannel( FakeClientConnectorChannel(
@ -106,7 +114,7 @@ class TestClient extends Client {
TestClient(base.ClientChannel channel, TestClient(base.ClientChannel channel,
{CallOptions? options, {CallOptions? options,
Iterable<ClientInterceptor>? interceptors, Iterable<ClientInterceptor>? interceptors,
this.decode: mockDecode}) this.decode = mockDecode})
: super(channel, options: options, interceptors: interceptors) { : super(channel, options: options, interceptors: interceptors) {
_$unary = ClientMethod<int, int>('/Test/Unary', mockEncode, decode); _$unary = ClientMethod<int, int>('/Test/Unary', mockEncode, decode);
_$clientStreaming = _$clientStreaming =
@ -255,7 +263,7 @@ abstract class _Harness {
List<MessageHandler> serverHandlers = const [], List<MessageHandler> serverHandlers = const [],
void Function()? doneHandler, void Function()? doneHandler,
bool expectDone = true}) async { bool expectDone = true}) async {
int serverHandlerIndex = 0; var serverHandlerIndex = 0;
void handleServerMessage(StreamMessage message) { void handleServerMessage(StreamMessage message) {
serverHandlers[serverHandlerIndex++](message); serverHandlers[serverHandlerIndex++](message);
} }

View File

@ -91,7 +91,9 @@ class TestInterceptor {
} }
class TestServerStream extends ServerTransportStream { class TestServerStream extends ServerTransportStream {
@override
final Stream<StreamMessage> incomingMessages; final Stream<StreamMessage> incomingMessages;
@override
final StreamSink<StreamMessage> outgoingMessages; final StreamSink<StreamMessage> outgoingMessages;
TestServerStream(this.incomingMessages, this.outgoingMessages); TestServerStream(this.incomingMessages, this.outgoingMessages);
@ -106,7 +108,7 @@ class TestServerStream extends ServerTransportStream {
} }
@override @override
set onTerminated(void value(int x)) {} set onTerminated(void Function(int x) value) {}
@override @override
bool get canPush => true; bool get canPush => true;
@ -162,7 +164,7 @@ abstract class _Harness {
} }
void setupTest(List<MessageHandler> handlers) { void setupTest(List<MessageHandler> handlers) {
int handlerIndex = 0; var handlerIndex = 0;
void handleMessages(StreamMessage message) { void handleMessages(StreamMessage message) {
handlers[handlerIndex++](message); handlers[handlerIndex++](message);
} }
@ -204,7 +206,7 @@ abstract class _Harness {
validateResponseHeaders(header.metadata); validateResponseHeaders(header.metadata);
} }
int responseIndex = 0; var responseIndex = 0;
void handleResponse(StreamMessage message) { void handleResponse(StreamMessage message) {
final response = validateDataMessage(message); final response = validateDataMessage(message);
expect(mockDecode(response.data), expectedResponses[responseIndex++]); expect(mockDecode(response.data), expectedResponses[responseIndex++]);

View File

@ -27,8 +27,7 @@ List<int> mockEncode(int value) => List.filled(value, 0);
int mockDecode(List<int> value) => value.length; int mockDecode(List<int> value) => value.length;
Map<String, String> headersToMap(List<Header> headers) => Map<String, String> headersToMap(List<Header> headers) =>
Map.fromIterable(headers, {for (var h in headers) ascii.decode(h.name): ascii.decode(h.value)};
key: (h) => ascii.decode(h.name), value: (h) => ascii.decode(h.value));
void validateRequestHeaders(Map<String, String> headers, void validateRequestHeaders(Map<String, String> headers,
{String? path, {String? path,

View File

@ -40,6 +40,7 @@ class TestClient extends Client {
} }
class TestService extends Service { class TestService extends Service {
@override
String get $name => 'test.TestService'; String get $name => 'test.TestService';
TestService() { TestService() {
@ -84,6 +85,7 @@ class FakeTimelineTask extends Fake implements TimelineTask {
bool get isComplete => _startFinishCount == 0; bool get isComplete => _startFinishCount == 0;
@override
void start(String name, {Map? arguments}) { void start(String name, {Map? arguments}) {
events.add({ events.add({
'id': id, 'id': id,
@ -98,6 +100,7 @@ class FakeTimelineTask extends Fake implements TimelineTask {
++_startFinishCount; ++_startFinishCount;
} }
@override
void instant(String name, {Map? arguments}) { void instant(String name, {Map? arguments}) {
events.add({ events.add({
'id': id, 'id': id,
@ -110,6 +113,7 @@ class FakeTimelineTask extends Fake implements TimelineTask {
}); });
} }
@override
void finish({Map? arguments}) { void finish({Map? arguments}) {
events.add({ events.add({
'id': id, 'id': id,
@ -128,8 +132,8 @@ TimelineTask fakeTimelineTaskFactory(
{String? filterKey, TimelineTask? parent}) => {String? filterKey, TimelineTask? parent}) =>
FakeTimelineTask(filterKey: filterKey, parent: parent); FakeTimelineTask(filterKey: filterKey, parent: parent);
testee() async { Future<void> testee() async {
final Server server = Server([TestService()]); final server = Server([TestService()]);
await server.serve(address: 'localhost', port: 0); await server.serve(address: 'localhost', port: 0);
isTimelineLoggingEnabled = true; isTimelineLoggingEnabled = true;
timelineTaskFactory = fakeTimelineTaskFactory; timelineTaskFactory = fakeTimelineTaskFactory;
@ -171,7 +175,7 @@ void checkWriteEvent(List<Map> events) {
void checkReceiveEvent(List<Map> events) { void checkReceiveEvent(List<Map> events) {
events = events.where((e) => e['name'] == 'Data received').toList(); events = events.where((e) => e['name'] == 'Data received').toList();
expect(events.length, equals(3)); expect(events.length, equals(3));
int sum = 0; var sum = 0;
for (final e in events) { for (final e in events) {
expect(e['id'], 1); expect(e['id'], 1);
// 3 elements are 1, 2 and 3. // 3 elements are 1, 2 and 3.
@ -200,7 +204,7 @@ void checkFinishEvent(List<Map> events) {
expect(e.length, 2); expect(e.length, 2);
} }
main([args = const <String>[]]) { void main([args = const <String>[]]) {
test('Test gRPC timeline logging', () async { test('Test gRPC timeline logging', () async {
await testee(); await testee();
for (final task in FakeTimelineTask.tasks) { for (final task in FakeTimelineTask.tasks) {

View File

@ -73,7 +73,7 @@ void main() {
test('Calls time out if deadline is exceeded', () async { test('Calls time out if deadline is exceeded', () async {
void handleRequest(StreamMessage message) { void handleRequest(StreamMessage message) {
validateDataMessage(message); validateDataMessage(message);
final Future delay = Future.delayed(Duration(milliseconds: 2)); final delay = Future.delayed(Duration(milliseconds: 2));
expect(delay, completes); expect(delay, completes);
delay.then((_) { delay.then((_) {
try { try {