[ Web ] Register service extensions with DDS, not DWDS (#79479)
This commit is contained in:
parent
437e32b9cf
commit
75a44a29ad
@ -17,6 +17,7 @@ import 'package:mime/mime.dart' as mime;
|
|||||||
import 'package:package_config/package_config.dart';
|
import 'package:package_config/package_config.dart';
|
||||||
import 'package:shelf/shelf.dart' as shelf;
|
import 'package:shelf/shelf.dart' as shelf;
|
||||||
import 'package:shelf/shelf_io.dart' as shelf;
|
import 'package:shelf/shelf_io.dart' as shelf;
|
||||||
|
import 'package:vm_service/vm_service.dart' as vm_service;
|
||||||
|
|
||||||
import '../artifacts.dart';
|
import '../artifacts.dart';
|
||||||
import '../asset.dart';
|
import '../asset.dart';
|
||||||
@ -35,6 +36,7 @@ import '../dart/package_map.dart';
|
|||||||
import '../devfs.dart';
|
import '../devfs.dart';
|
||||||
import '../globals.dart' as globals;
|
import '../globals.dart' as globals;
|
||||||
import '../project.dart';
|
import '../project.dart';
|
||||||
|
import '../vmservice.dart';
|
||||||
import '../web/bootstrap.dart';
|
import '../web/bootstrap.dart';
|
||||||
import '../web/chrome.dart';
|
import '../web/chrome.dart';
|
||||||
import '../web/compile.dart';
|
import '../web/compile.dart';
|
||||||
@ -592,10 +594,11 @@ class WebAssetServer implements AssetReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ConnectionResult {
|
class ConnectionResult {
|
||||||
ConnectionResult(this.appConnection, this.debugConnection);
|
ConnectionResult(this.appConnection, this.debugConnection, this.vmService);
|
||||||
|
|
||||||
final AppConnection appConnection;
|
final AppConnection appConnection;
|
||||||
final DebugConnection debugConnection;
|
final DebugConnection debugConnection;
|
||||||
|
final vm_service.VmService vmService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The web specific DevFS implementation.
|
/// The web specific DevFS implementation.
|
||||||
@ -665,8 +668,12 @@ class WebDevFS implements DevFS {
|
|||||||
if (firstConnection.isCompleted) {
|
if (firstConnection.isCompleted) {
|
||||||
appConnection.runMain();
|
appConnection.runMain();
|
||||||
} else {
|
} else {
|
||||||
|
final vm_service.VmService vmService = await createVmServiceDelegate(
|
||||||
|
Uri.parse(debugConnection.uri),
|
||||||
|
logger: globals.logger,
|
||||||
|
);
|
||||||
firstConnection
|
firstConnection
|
||||||
.complete(ConnectionResult(appConnection, debugConnection));
|
.complete(ConnectionResult(appConnection, debugConnection, vmService));
|
||||||
}
|
}
|
||||||
} on Exception catch (error, stackTrace) {
|
} on Exception catch (error, stackTrace) {
|
||||||
if (!firstConnection.isCompleted) {
|
if (!firstConnection.isCompleted) {
|
||||||
|
@ -155,7 +155,7 @@ class ResidentWebRunner extends ResidentRunner {
|
|||||||
if (_instance != null) {
|
if (_instance != null) {
|
||||||
return _instance;
|
return _instance;
|
||||||
}
|
}
|
||||||
final vmservice.VmService service =_connectionResult?.debugConnection?.vmService;
|
final vmservice.VmService service =_connectionResult?.vmService;
|
||||||
final Uri websocketUri = Uri.parse(_connectionResult.debugConnection.uri);
|
final Uri websocketUri = Uri.parse(_connectionResult.debugConnection.uri);
|
||||||
final Uri httpUri = _httpUriFromWebsocketUri(websocketUri);
|
final Uri httpUri = _httpUriFromWebsocketUri(websocketUri);
|
||||||
return _instance ??= FlutterVmService(service, wsAddress: websocketUri, httpAddress: httpUri);
|
return _instance ??= FlutterVmService(service, wsAddress: websocketUri, httpAddress: httpUri);
|
||||||
@ -835,7 +835,7 @@ class ResidentWebRunner extends ResidentRunner {
|
|||||||
_connectionResult.appConnection.runMain();
|
_connectionResult.appConnection.runMain();
|
||||||
} else {
|
} else {
|
||||||
StreamSubscription<void> resumeSub;
|
StreamSubscription<void> resumeSub;
|
||||||
resumeSub = _connectionResult.debugConnection.vmService.onDebugEvent
|
resumeSub = _vmService.service.onDebugEvent
|
||||||
.listen((vmservice.Event event) {
|
.listen((vmservice.Event event) {
|
||||||
if (event.type == vmservice.EventKind.kResume) {
|
if (event.type == vmservice.EventKind.kResume) {
|
||||||
_connectionResult.appConnection.runMain();
|
_connectionResult.appConnection.runMain();
|
||||||
|
@ -326,6 +326,22 @@ Future<FlutterVmService> connectToVmService(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<vm_service.VmService> createVmServiceDelegate(
|
||||||
|
Uri wsUri, {
|
||||||
|
io.CompressionOptions compression = io.CompressionOptions.compressionDefault,
|
||||||
|
@required Logger logger,
|
||||||
|
}) async {
|
||||||
|
final io.WebSocket channel = await _openChannel(wsUri.toString(), compression: compression, logger: logger);
|
||||||
|
return vm_service.VmService(
|
||||||
|
channel,
|
||||||
|
channel.add,
|
||||||
|
log: null,
|
||||||
|
disposeHandler: () async {
|
||||||
|
await channel.close();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Future<FlutterVmService> _connect(
|
Future<FlutterVmService> _connect(
|
||||||
Uri httpUri, {
|
Uri httpUri, {
|
||||||
ReloadSources reloadSources,
|
ReloadSources reloadSources,
|
||||||
@ -338,14 +354,8 @@ Future<FlutterVmService> _connect(
|
|||||||
@required Logger logger,
|
@required Logger logger,
|
||||||
}) async {
|
}) async {
|
||||||
final Uri wsUri = httpUri.replace(scheme: 'ws', path: urlContext.join(httpUri.path, 'ws'));
|
final Uri wsUri = httpUri.replace(scheme: 'ws', path: urlContext.join(httpUri.path, 'ws'));
|
||||||
final io.WebSocket channel = await _openChannel(wsUri.toString(), compression: compression, logger: logger);
|
final vm_service.VmService delegateService = await createVmServiceDelegate(
|
||||||
final vm_service.VmService delegateService = vm_service.VmService(
|
wsUri, compression: compression, logger: logger,
|
||||||
channel,
|
|
||||||
channel.add,
|
|
||||||
log: null,
|
|
||||||
disposeHandler: () async {
|
|
||||||
await channel.close();
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
final vm_service.VmService service = await setUpVmService(
|
final vm_service.VmService service = await setUpVmService(
|
||||||
|
@ -130,7 +130,11 @@ void main() {
|
|||||||
when(mockFlutterDevice.devFS).thenReturn(mockWebDevFS);
|
when(mockFlutterDevice.devFS).thenReturn(mockWebDevFS);
|
||||||
when(mockFlutterDevice.device).thenReturn(mockDevice);
|
when(mockFlutterDevice.device).thenReturn(mockDevice);
|
||||||
when(mockWebDevFS.connect(any)).thenAnswer((Invocation invocation) async {
|
when(mockWebDevFS.connect(any)).thenAnswer((Invocation invocation) async {
|
||||||
return ConnectionResult(mockAppConnection, mockDebugConnection);
|
return ConnectionResult(
|
||||||
|
mockAppConnection,
|
||||||
|
mockDebugConnection,
|
||||||
|
mockDebugConnection.vmService,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
fileSystem.file('.packages').writeAsStringSync('\n');
|
fileSystem.file('.packages').writeAsStringSync('\n');
|
||||||
});
|
});
|
||||||
|
@ -63,6 +63,7 @@ abstract class FlutterTestDriver {
|
|||||||
Stream<String> get stdout => _stdout.stream;
|
Stream<String> get stdout => _stdout.stream;
|
||||||
int get vmServicePort => _vmServiceWsUri.port;
|
int get vmServicePort => _vmServiceWsUri.port;
|
||||||
bool get hasExited => _hasExited;
|
bool get hasExited => _hasExited;
|
||||||
|
Uri get vmServiceWsUri => _vmServiceWsUri;
|
||||||
|
|
||||||
String lastTime = '';
|
String lastTime = '';
|
||||||
void _debugPrint(String message, { String topic = '' }) {
|
void _debugPrint(String message, { String topic = '' }) {
|
||||||
@ -219,7 +220,7 @@ abstract class FlutterTestDriver {
|
|||||||
return _flutterIsolateId;
|
return _flutterIsolateId;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Isolate> _getFlutterIsolate() async {
|
Future<Isolate> getFlutterIsolate() async {
|
||||||
final Isolate isolate = await _vmService.getIsolate(await _getFlutterIsolateId());
|
final Isolate isolate = await _vmService.getIsolate(await _getFlutterIsolateId());
|
||||||
return isolate;
|
return isolate;
|
||||||
}
|
}
|
||||||
@ -281,7 +282,7 @@ abstract class FlutterTestDriver {
|
|||||||
// Cancel the subscription on either of the above.
|
// Cancel the subscription on either of the above.
|
||||||
await pauseSubscription.cancel();
|
await pauseSubscription.cancel();
|
||||||
|
|
||||||
return _getFlutterIsolate();
|
return getFlutterIsolate();
|
||||||
},
|
},
|
||||||
task: 'Waiting for isolate to pause',
|
task: 'Waiting for isolate to pause',
|
||||||
);
|
);
|
||||||
@ -294,7 +295,7 @@ abstract class FlutterTestDriver {
|
|||||||
Future<Isolate> stepOut({ bool waitForNextPause = true }) => _resume(StepOption.kOut, waitForNextPause);
|
Future<Isolate> stepOut({ bool waitForNextPause = true }) => _resume(StepOption.kOut, waitForNextPause);
|
||||||
|
|
||||||
Future<bool> isAtAsyncSuspension() async {
|
Future<bool> isAtAsyncSuspension() async {
|
||||||
final Isolate isolate = await _getFlutterIsolate();
|
final Isolate isolate = await getFlutterIsolate();
|
||||||
return isolate.pauseEvent.atAsyncSuspension == true;
|
return isolate.pauseEvent.atAsyncSuspension == true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,160 +13,163 @@ import '../integration.shard/test_driver.dart';
|
|||||||
import '../integration.shard/test_utils.dart';
|
import '../integration.shard/test_utils.dart';
|
||||||
import '../src/common.dart';
|
import '../src/common.dart';
|
||||||
|
|
||||||
void batch1() {
|
void main() {
|
||||||
final BasicProject _project = BasicProject();
|
group('Flutter run for web', () {
|
||||||
Directory tempDir;
|
final BasicProject project = BasicProject();
|
||||||
FlutterRunTestDriver _flutter;
|
Directory tempDir;
|
||||||
|
FlutterRunTestDriver flutter;
|
||||||
|
|
||||||
Future<void> initProject() async {
|
setUp(() async {
|
||||||
tempDir = createResolvedTempDirectorySync('run_expression_eval_test.');
|
tempDir = createResolvedTempDirectorySync('run_expression_eval_test.');
|
||||||
await _project.setUpIn(tempDir);
|
await project.setUpIn(tempDir);
|
||||||
_flutter = FlutterRunTestDriver(tempDir);
|
flutter = FlutterRunTestDriver(tempDir);
|
||||||
}
|
});
|
||||||
|
|
||||||
Future<void> cleanProject() async {
|
tearDown(() async {
|
||||||
await _flutter.stop();
|
await flutter.stop();
|
||||||
tryToDelete(tempDir);
|
tryToDelete(tempDir);
|
||||||
}
|
});
|
||||||
|
|
||||||
Future<void> start({bool expressionEvaluation}) {
|
Future<void> start({bool expressionEvaluation}) async {
|
||||||
// The non-test project has a loop around its breakpoints.
|
// The non-test project has a loop around its breakpoints.
|
||||||
// No need to start paused as all breakpoint would be eventually reached.
|
// No need to start paused as all breakpoint would be eventually reached.
|
||||||
return _flutter.run(
|
await flutter.run(
|
||||||
withDebugger: true, chrome: true,
|
withDebugger: true, chrome: true,
|
||||||
expressionEvaluation: expressionEvaluation,
|
expressionEvaluation: expressionEvaluation,
|
||||||
additionalCommandArgs: <String>['--verbose']);
|
additionalCommandArgs: <String>['--verbose']);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> breakInBuildMethod(FlutterTestDriver flutter) async {
|
Future<void> breakInBuildMethod(FlutterTestDriver flutter) async {
|
||||||
await _flutter.breakAt(
|
await flutter.breakAt(
|
||||||
_project.buildMethodBreakpointUri,
|
project.buildMethodBreakpointUri,
|
||||||
_project.buildMethodBreakpointLine,
|
project.buildMethodBreakpointLine,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> breakInTopLevelFunction(FlutterTestDriver flutter) async {
|
Future<void> breakInTopLevelFunction(FlutterTestDriver flutter) async {
|
||||||
await _flutter.breakAt(
|
await flutter.breakAt(
|
||||||
_project.topLevelFunctionBreakpointUri,
|
project.topLevelFunctionBreakpointUri,
|
||||||
_project.topLevelFunctionBreakpointLine,
|
project.topLevelFunctionBreakpointLine,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
testWithoutContext('flutter run expression evaluation - error if expression evaluation disabled', () async {
|
testWithoutContext('cannot evaluate expression if feature is disabled', () async {
|
||||||
await initProject();
|
await start(expressionEvaluation: false);
|
||||||
await start(expressionEvaluation: false);
|
await breakInTopLevelFunction(flutter);
|
||||||
await breakInTopLevelFunction(_flutter);
|
await failToEvaluateExpression(flutter);
|
||||||
await failToEvaluateExpression(_flutter);
|
});
|
||||||
await cleanProject();
|
|
||||||
|
testWithoutContext('shows no native javascript objects in static scope', () async {
|
||||||
|
await start(expressionEvaluation: true);
|
||||||
|
await breakInTopLevelFunction(flutter);
|
||||||
|
await checkStaticScope(flutter);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWithoutContext('can handle compilation errors', () async {
|
||||||
|
await start(expressionEvaluation: true);
|
||||||
|
await breakInTopLevelFunction(flutter);
|
||||||
|
await evaluateErrorExpressions(flutter);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWithoutContext('can evaluate trivial expressions in top level function', () async {
|
||||||
|
await start(expressionEvaluation: true);
|
||||||
|
await breakInTopLevelFunction(flutter);
|
||||||
|
await evaluateTrivialExpressions(flutter);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWithoutContext('can evaluate trivial expressions in build method', () async {
|
||||||
|
await start(expressionEvaluation: true);
|
||||||
|
await breakInBuildMethod(flutter);
|
||||||
|
await evaluateTrivialExpressions(flutter);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWithoutContext('can evaluate complex expressions in top level function', () async {
|
||||||
|
await start(expressionEvaluation: true);
|
||||||
|
await breakInTopLevelFunction(flutter);
|
||||||
|
await evaluateComplexExpressions(flutter);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWithoutContext('can evaluate complex expressions in build method', () async {
|
||||||
|
await start(expressionEvaluation: true);
|
||||||
|
await breakInBuildMethod(flutter);
|
||||||
|
await evaluateComplexExpressions(flutter);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWithoutContext('can evaluate trivial expressions in library without pause', () async {
|
||||||
|
await start(expressionEvaluation: true);
|
||||||
|
await evaluateTrivialExpressionsInLibrary(flutter);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWithoutContext('can evaluate complex expressions in library without pause', () async {
|
||||||
|
await start(expressionEvaluation: true);
|
||||||
|
await evaluateComplexExpressionsInLibrary(flutter);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('flutter run expression evaluation - no native javascript objects in static scope', () async {
|
|
||||||
await initProject();
|
|
||||||
await start(expressionEvaluation: true);
|
|
||||||
await breakInTopLevelFunction(_flutter);
|
|
||||||
await checkStaticScope(_flutter);
|
|
||||||
await cleanProject();
|
|
||||||
});
|
|
||||||
|
|
||||||
testWithoutContext('flutter run expression evaluation - can handle compilation errors', () async {
|
group('Flutter test for web', () {
|
||||||
await initProject();
|
final TestsProject project = TestsProject();
|
||||||
await start(expressionEvaluation: true);
|
Directory tempDir;
|
||||||
await breakInTopLevelFunction(_flutter);
|
FlutterRunTestDriver flutter;
|
||||||
await evaluateErrorExpressions(_flutter);
|
|
||||||
await cleanProject();
|
|
||||||
});
|
|
||||||
|
|
||||||
testWithoutContext('flutter run expression evaluation - can evaluate trivial expressions in top level function', () async {
|
setUp(() async {
|
||||||
await initProject();
|
tempDir = createResolvedTempDirectorySync('run_expression_eval_test.');
|
||||||
await start(expressionEvaluation: true);
|
await project.setUpIn(tempDir);
|
||||||
await breakInTopLevelFunction(_flutter);
|
flutter = FlutterRunTestDriver(tempDir);
|
||||||
await evaluateTrivialExpressions(_flutter);
|
});
|
||||||
await cleanProject();
|
|
||||||
});
|
|
||||||
|
|
||||||
testWithoutContext('flutter run expression evaluation - can evaluate trivial expressions in build method', () async {
|
tearDown(() async {
|
||||||
await initProject();
|
await flutter.stop();
|
||||||
await start(expressionEvaluation: true);
|
tryToDelete(tempDir);
|
||||||
await breakInBuildMethod(_flutter);
|
});
|
||||||
await evaluateTrivialExpressions(_flutter);
|
|
||||||
await cleanProject();
|
|
||||||
});
|
|
||||||
|
|
||||||
testWithoutContext('flutter run expression evaluation - can evaluate complex expressions in top level function', () async {
|
Future<Isolate> breakInMethod(FlutterTestDriver flutter) async {
|
||||||
await initProject();
|
await flutter.addBreakpoint(
|
||||||
await start(expressionEvaluation: true);
|
project.breakpointAppUri,
|
||||||
await breakInTopLevelFunction(_flutter);
|
project.breakpointLine,
|
||||||
await evaluateComplexExpressions(_flutter);
|
);
|
||||||
await cleanProject();
|
await flutter.resume();
|
||||||
});
|
return flutter.waitForPause();
|
||||||
|
}
|
||||||
|
|
||||||
testWithoutContext('flutter run expression evaluation - can evaluate complex expressions in build method', () async {
|
Future<void> startPaused({bool expressionEvaluation}) {
|
||||||
await initProject();
|
// The test project does not have a loop around its breakpoints.
|
||||||
await _flutter.run(withDebugger: true, chrome: true);
|
// Start paused so we can set a breakpoint before passing it
|
||||||
await breakInBuildMethod(_flutter);
|
// in the execution.
|
||||||
await evaluateComplexExpressions(_flutter);
|
return flutter.run(
|
||||||
await cleanProject();
|
withDebugger: true, chrome: true,
|
||||||
});
|
expressionEvaluation: expressionEvaluation,
|
||||||
}
|
startPaused: true, script: project.testFilePath,
|
||||||
|
additionalCommandArgs: <String>['--verbose']);
|
||||||
|
}
|
||||||
|
|
||||||
void batch2() {
|
testWithoutContext('cannot evaluate expressions if feature is disabled', () async {
|
||||||
final TestsProject _project = TestsProject();
|
await startPaused(expressionEvaluation: false);
|
||||||
Directory tempDir;
|
await breakInMethod(flutter);
|
||||||
FlutterRunTestDriver _flutter;
|
await failToEvaluateExpression(flutter);
|
||||||
|
});
|
||||||
|
|
||||||
Future<void> initProject() async {
|
testWithoutContext('can evaluate trivial expressions in a test', () async {
|
||||||
tempDir = createResolvedTempDirectorySync('test_expression_eval_test.');
|
await startPaused(expressionEvaluation: true);
|
||||||
await _project.setUpIn(tempDir);
|
await breakInMethod(flutter);
|
||||||
_flutter = FlutterRunTestDriver(tempDir);
|
await evaluateTrivialExpressions(flutter);
|
||||||
}
|
});
|
||||||
|
|
||||||
Future<void> cleanProject() async {
|
testWithoutContext('can evaluate complex expressions in a test', () async {
|
||||||
await _flutter.stop();
|
await startPaused(expressionEvaluation: true);
|
||||||
tryToDelete(tempDir);
|
await breakInMethod(flutter);
|
||||||
}
|
await evaluateComplexExpressions(flutter);
|
||||||
|
});
|
||||||
|
|
||||||
Future<void> breakInMethod(FlutterTestDriver flutter) async {
|
testWithoutContext('can evaluate trivial expressions in library without pause', () async {
|
||||||
await _flutter.addBreakpoint(
|
await startPaused(expressionEvaluation: true);
|
||||||
_project.breakpointAppUri,
|
await evaluateTrivialExpressionsInLibrary(flutter);
|
||||||
_project.breakpointLine,
|
});
|
||||||
);
|
|
||||||
await _flutter.resume();
|
|
||||||
await _flutter.waitForPause();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> startPaused({bool expressionEvaluation}) {
|
testWithoutContext('can evaluate complex expressions in library without pause', () async {
|
||||||
// The test project does not have a loop around its breakpoints.
|
await startPaused(expressionEvaluation: true);
|
||||||
// Start paused so we can set a breakpoint before passing it
|
await evaluateComplexExpressionsInLibrary(flutter);
|
||||||
// in the execution.
|
});
|
||||||
return _flutter.run(
|
|
||||||
withDebugger: true, chrome: true,
|
|
||||||
expressionEvaluation: expressionEvaluation,
|
|
||||||
startPaused: true, script: _project.testFilePath,
|
|
||||||
additionalCommandArgs: <String>['--verbose']);
|
|
||||||
}
|
|
||||||
|
|
||||||
testWithoutContext('flutter test expression evaluation - error if expression evaluation disabled', () async {
|
|
||||||
await initProject();
|
|
||||||
await startPaused(expressionEvaluation: false);
|
|
||||||
await breakInMethod(_flutter);
|
|
||||||
await failToEvaluateExpression(_flutter);
|
|
||||||
await cleanProject();
|
|
||||||
});
|
|
||||||
|
|
||||||
testWithoutContext('flutter test expression evaluation - can evaluate trivial expressions in a test', () async {
|
|
||||||
await initProject();
|
|
||||||
await startPaused(expressionEvaluation: true);
|
|
||||||
await breakInMethod(_flutter);
|
|
||||||
await evaluateTrivialExpressions(_flutter);
|
|
||||||
await cleanProject();
|
|
||||||
});
|
|
||||||
|
|
||||||
testWithoutContext('flutter test expression evaluation - can evaluate complex expressions in a test', () async {
|
|
||||||
await initProject();
|
|
||||||
await startPaused(expressionEvaluation: true);
|
|
||||||
await breakInMethod(_flutter);
|
|
||||||
await evaluateComplexExpressions(_flutter);
|
|
||||||
await cleanProject();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,6 +211,28 @@ Future<void> evaluateComplexExpressions(FlutterTestDriver flutter) async {
|
|||||||
expectInstance(res, InstanceKind.kDouble, DateTime.now().year.toString());
|
expectInstance(res, InstanceKind.kDouble, DateTime.now().year.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> evaluateTrivialExpressionsInLibrary(FlutterTestDriver flutter) async {
|
||||||
|
final LibraryRef library = await getRootLibrary(flutter);
|
||||||
|
final ObjRef res = await flutter.evaluate(library.id, '"test"');
|
||||||
|
expectInstance(res, InstanceKind.kString, 'test');
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> evaluateComplexExpressionsInLibrary(FlutterTestDriver flutter) async {
|
||||||
|
final LibraryRef library = await getRootLibrary(flutter);
|
||||||
|
final ObjRef res = await flutter.evaluate(library.id, 'new DateTime.now().year');
|
||||||
|
expectInstance(res, InstanceKind.kDouble, DateTime.now().year.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<LibraryRef> getRootLibrary(FlutterTestDriver flutter) async {
|
||||||
|
// `isolate.rootLib` returns incorrect library, so find the
|
||||||
|
// entrypoint manually here instead.
|
||||||
|
//
|
||||||
|
// Issue: https://github.com/dart-lang/sdk/issues/44760
|
||||||
|
final Isolate isolate = await flutter.getFlutterIsolate();
|
||||||
|
return isolate.libraries
|
||||||
|
.firstWhere((LibraryRef l) => l.uri.contains('org-dartlang-app'));
|
||||||
|
}
|
||||||
|
|
||||||
void expectInstance(ObjRef result, String kind, String message) {
|
void expectInstance(ObjRef result, String kind, String message) {
|
||||||
expect(result,
|
expect(result,
|
||||||
const TypeMatcher<InstanceRef>()
|
const TypeMatcher<InstanceRef>()
|
||||||
@ -220,8 +245,3 @@ void expectError(ObjRef result, String message) {
|
|||||||
const TypeMatcher<ErrorRef>()
|
const TypeMatcher<ErrorRef>()
|
||||||
.having((ErrorRef instance) => instance.message, 'message', message));
|
.having((ErrorRef instance) => instance.message, 'message', message));
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
|
||||||
batch1();
|
|
||||||
batch2();
|
|
||||||
}
|
|
||||||
|
139
packages/flutter_tools/test/web.shard/vm_service_web_test.dart
Normal file
139
packages/flutter_tools/test/web.shard/vm_service_web_test.dart
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
// @dart = 2.8
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:file/file.dart';
|
||||||
|
import 'package:flutter_tools/src/base/file_system.dart';
|
||||||
|
import 'package:vm_service/vm_service.dart';
|
||||||
|
import 'package:vm_service/vm_service_io.dart';
|
||||||
|
|
||||||
|
import '../integration.shard/test_data/basic_project.dart';
|
||||||
|
import '../integration.shard/test_driver.dart';
|
||||||
|
import '../integration.shard/test_utils.dart';
|
||||||
|
import '../src/common.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
Directory tempDir;
|
||||||
|
final BasicProjectWithUnaryMain project = BasicProjectWithUnaryMain();
|
||||||
|
FlutterRunTestDriver flutter;
|
||||||
|
|
||||||
|
group('Clients of flutter run on web with DDS enabled', () {
|
||||||
|
setUp(() async {
|
||||||
|
tempDir = createResolvedTempDirectorySync('run_test.');
|
||||||
|
await project.setUpIn(tempDir);
|
||||||
|
flutter = FlutterRunTestDriver(tempDir, spawnDdsInstance: true);
|
||||||
|
});
|
||||||
|
|
||||||
|
tearDown(() async {
|
||||||
|
await flutter.stop();
|
||||||
|
tryToDelete(tempDir);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWithoutContext('can validate flutter version', () async {
|
||||||
|
await flutter.run(
|
||||||
|
withDebugger: true, chrome: true,
|
||||||
|
additionalCommandArgs: <String>['--verbose']);
|
||||||
|
|
||||||
|
expect(flutter.vmServiceWsUri, isNotNull);
|
||||||
|
|
||||||
|
final VmService client =
|
||||||
|
await vmServiceConnectUri('${flutter.vmServiceWsUri}');
|
||||||
|
await validateFlutterVersion(client);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWithoutContext('can validate flutter version in parallel', () async {
|
||||||
|
await flutter.run(
|
||||||
|
withDebugger: true, chrome: true,
|
||||||
|
additionalCommandArgs: <String>['--verbose']);
|
||||||
|
|
||||||
|
expect(flutter.vmServiceWsUri, isNotNull);
|
||||||
|
|
||||||
|
final VmService client1 =
|
||||||
|
await vmServiceConnectUri('${flutter.vmServiceWsUri}');
|
||||||
|
|
||||||
|
final VmService client2 =
|
||||||
|
await vmServiceConnectUri('${flutter.vmServiceWsUri}');
|
||||||
|
|
||||||
|
await Future.wait(<Future<void>>[
|
||||||
|
validateFlutterVersion(client1),
|
||||||
|
validateFlutterVersion(client2)]
|
||||||
|
);
|
||||||
|
}, skip: 'DDS failure: https://github.com/dart-lang/sdk/issues/45569');
|
||||||
|
});
|
||||||
|
|
||||||
|
group('Clients of flutter run on web with DDS disabled', () {
|
||||||
|
setUp(() async {
|
||||||
|
tempDir = createResolvedTempDirectorySync('run_test.');
|
||||||
|
await project.setUpIn(tempDir);
|
||||||
|
flutter = FlutterRunTestDriver(tempDir, spawnDdsInstance: false);
|
||||||
|
});
|
||||||
|
|
||||||
|
tearDown(() async {
|
||||||
|
await flutter.stop();
|
||||||
|
tryToDelete(tempDir);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWithoutContext('can validate flutter version', () async {
|
||||||
|
await flutter.run(
|
||||||
|
withDebugger: true, chrome: true,
|
||||||
|
additionalCommandArgs: <String>['--verbose']);
|
||||||
|
|
||||||
|
expect(flutter.vmServiceWsUri, isNotNull);
|
||||||
|
|
||||||
|
final VmService client =
|
||||||
|
await vmServiceConnectUri('${flutter.vmServiceWsUri}');
|
||||||
|
await validateFlutterVersion(client);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
testWithoutContext('can validate flutter version in parallel', () async {
|
||||||
|
await flutter.run(
|
||||||
|
withDebugger: true, chrome: true,
|
||||||
|
additionalCommandArgs: <String>['--verbose']);
|
||||||
|
|
||||||
|
expect(flutter.vmServiceWsUri, isNotNull);
|
||||||
|
|
||||||
|
final VmService client1 =
|
||||||
|
await vmServiceConnectUri('${flutter.vmServiceWsUri}');
|
||||||
|
|
||||||
|
final VmService client2 =
|
||||||
|
await vmServiceConnectUri('${flutter.vmServiceWsUri}');
|
||||||
|
|
||||||
|
await Future.wait(<Future<void>>[
|
||||||
|
validateFlutterVersion(client1),
|
||||||
|
validateFlutterVersion(client2)]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> validateFlutterVersion(VmService client) async {
|
||||||
|
String method;
|
||||||
|
|
||||||
|
final Future<dynamic> registration = expectLater(
|
||||||
|
client.onEvent('Service'),
|
||||||
|
emitsThrough(predicate((Event e) {
|
||||||
|
if (e.kind == EventKind.kServiceRegistered &&
|
||||||
|
e.service == 'flutterVersion') {
|
||||||
|
method = e.method;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
|
await client.streamListen('Service');
|
||||||
|
await registration;
|
||||||
|
await client.streamCancel('Service');
|
||||||
|
|
||||||
|
final dynamic version1 = await client.callServiceExtension(method);
|
||||||
|
expect(version1, const TypeMatcher<Success>()
|
||||||
|
.having((Success r) => r.type, 'type', 'Success')
|
||||||
|
.having((Success r) => r.json['frameworkVersion'], 'frameworkVersion', isNotNull));
|
||||||
|
|
||||||
|
await client.dispose();
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user