mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00

In service of https://github.com/flutter/flutter/issues/146879. See https://github.com/flutter/flutter/issues/146879#issuecomment-2108784673 in particular for the purpose of this PR. This adds a few more `printTrace` calls to try to see where we are getting stuck.
140 lines
4.1 KiB
Dart
140 lines
4.1 KiB
Dart
// Copyright 2014 The Flutter Authors. 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 'package:flutter_tools/src/base/logger.dart';
|
|
import 'package:flutter_tools/src/convert.dart';
|
|
import 'package:flutter_tools/src/vmservice.dart';
|
|
import 'package:test/test.dart' hide test;
|
|
import 'package:vm_service/vm_service.dart' as vm_service;
|
|
|
|
export 'package:test/test.dart' hide isInstanceOf, test;
|
|
|
|
/// A fake implementation of a vm_service that mocks the JSON-RPC request
|
|
/// and response structure.
|
|
class FakeVmServiceHost {
|
|
FakeVmServiceHost({
|
|
required List<VmServiceExpectation> requests,
|
|
Uri? httpAddress,
|
|
Uri? wsAddress,
|
|
}) : _requests = requests {
|
|
_vmService = FlutterVmService(vm_service.VmService(
|
|
_input.stream,
|
|
_output.add,
|
|
), httpAddress: httpAddress, wsAddress: wsAddress, logger: BufferLogger.test());
|
|
_applyStreamListen();
|
|
_output.stream.listen((String data) {
|
|
final Map<String, Object?> request = json.decode(data) as Map<String, Object?>;
|
|
if (_requests.isEmpty) {
|
|
throw Exception('Unexpected request: $request');
|
|
}
|
|
final FakeVmServiceRequest fakeRequest = _requests.removeAt(0) as FakeVmServiceRequest;
|
|
expect(request, isA<Map<String, Object?>>()
|
|
.having((Map<String, Object?> request) => request['method'], 'method', fakeRequest.method)
|
|
.having((Map<String, Object?> request) => request['params'], 'args', fakeRequest.args)
|
|
);
|
|
if (fakeRequest.close) {
|
|
unawaited(_vmService.dispose());
|
|
expect(_requests, isEmpty);
|
|
return;
|
|
}
|
|
if (fakeRequest.error == null) {
|
|
_input.add(json.encode(<String, Object?>{
|
|
'jsonrpc': '2.0',
|
|
'id': request['id'],
|
|
'result': fakeRequest.jsonResponse ?? <String, Object>{'type': 'Success'},
|
|
}));
|
|
} else {
|
|
_input.add(json.encode(<String, Object?>{
|
|
'jsonrpc': '2.0',
|
|
'id': request['id'],
|
|
'error': <String, Object?>{
|
|
'code': fakeRequest.error!.code,
|
|
'message': fakeRequest.error!.error,
|
|
},
|
|
}));
|
|
}
|
|
_applyStreamListen();
|
|
});
|
|
}
|
|
|
|
final List<VmServiceExpectation> _requests;
|
|
final StreamController<String> _input = StreamController<String>();
|
|
final StreamController<String> _output = StreamController<String>();
|
|
|
|
FlutterVmService get vmService => _vmService;
|
|
late final FlutterVmService _vmService;
|
|
|
|
|
|
bool get hasRemainingExpectations => _requests.isNotEmpty;
|
|
|
|
// remove FakeStreamResponse objects from _requests until it is empty
|
|
// or until we hit a FakeRequest
|
|
void _applyStreamListen() {
|
|
while (_requests.isNotEmpty && !_requests.first.isRequest) {
|
|
final FakeVmServiceStreamResponse response = _requests.removeAt(0) as FakeVmServiceStreamResponse;
|
|
_input.add(json.encode(<String, Object>{
|
|
'jsonrpc': '2.0',
|
|
'method': 'streamNotify',
|
|
'params': <String, Object>{
|
|
'streamId': response.streamId,
|
|
'event': response.event.toJson(),
|
|
},
|
|
}));
|
|
}
|
|
}
|
|
}
|
|
|
|
abstract class VmServiceExpectation {
|
|
bool get isRequest;
|
|
}
|
|
|
|
class FakeRPCError {
|
|
const FakeRPCError({
|
|
required this.code,
|
|
this.error = 'error',
|
|
});
|
|
|
|
final int code;
|
|
final String error;
|
|
}
|
|
|
|
class FakeVmServiceRequest implements VmServiceExpectation {
|
|
const FakeVmServiceRequest({
|
|
required this.method,
|
|
this.args = const <String, Object?>{},
|
|
this.jsonResponse,
|
|
this.error,
|
|
this.close = false,
|
|
});
|
|
|
|
final String method;
|
|
|
|
/// When true, the vm service is automatically closed.
|
|
final bool close;
|
|
|
|
/// If non-null, the error code for a [vm_service.RPCError] in place of a
|
|
/// standard response.
|
|
final FakeRPCError? error;
|
|
final Map<String, Object?>? args;
|
|
final Map<String, Object?>? jsonResponse;
|
|
|
|
@override
|
|
bool get isRequest => true;
|
|
}
|
|
|
|
class FakeVmServiceStreamResponse implements VmServiceExpectation {
|
|
const FakeVmServiceStreamResponse({
|
|
required this.event,
|
|
required this.streamId,
|
|
});
|
|
|
|
final vm_service.Event event;
|
|
final String streamId;
|
|
|
|
@override
|
|
bool get isRequest => false;
|
|
}
|