| // 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 'package:file/memory.dart'; |
| import 'package:flutter_tools/src/base/file_system.dart'; |
| import 'package:flutter_tools/src/build_info.dart'; |
| import 'package:flutter_tools/src/compile.dart'; |
| import 'package:flutter_tools/src/devfs.dart'; |
| import 'package:flutter_tools/src/device.dart'; |
| import 'package:flutter_tools/src/resident_runner.dart'; |
| import 'package:flutter_tools/src/run_hot.dart'; |
| import 'package:flutter_tools/src/vmservice.dart'; |
| import 'package:test/fake.dart'; |
| import 'package:unified_analytics/unified_analytics.dart'; |
| import 'package:vm_service/vm_service.dart' as vm_service; |
| |
| import '../src/common.dart'; |
| import '../src/context.dart'; |
| import 'hot_shared.dart'; |
| |
| void main() { |
| testWithoutContext('defaultReloadSourcesHelper() handles empty DeviceReloadReports)', () { |
| defaultReloadSourcesHelper( |
| _FakeHotRunner(), |
| <FlutterDevice?>[_FakeFlutterDevice()], |
| false, |
| const <String, dynamic>{}, |
| 'android', |
| 'flutter-sdk', |
| false, |
| 'test-reason', |
| const NoOpAnalytics(), |
| ); |
| }); |
| |
| group('signal handling', () { |
| late _FakeHotCompatibleFlutterDevice flutterDevice; |
| late MemoryFileSystem fileSystem; |
| |
| setUp(() { |
| flutterDevice = _FakeHotCompatibleFlutterDevice(FakeDevice()); |
| fileSystem = MemoryFileSystem.test(); |
| }); |
| |
| testUsingContext( |
| 'kills the test device', |
| () async { |
| final runner = HotRunner( |
| <FlutterDevice>[flutterDevice], |
| target: 'main.dart', |
| debuggingOptions: DebuggingOptions.disabled(BuildInfo.debug), |
| analytics: _FakeAnalytics(), |
| ); |
| |
| await runner.run(); |
| await runner.cleanupAfterSignal(); |
| expect(flutterDevice.wasExited, true); |
| expect((flutterDevice.device.dds as FakeDartDevelopmentService).wasShutdown, true); |
| }, |
| overrides: <Type, Generator>{ |
| FileSystem: () => fileSystem, |
| ProcessManager: FakeProcessManager.empty, |
| }, |
| ); |
| |
| testUsingContext( |
| 'kill with a detach keeps the test device running', |
| () async { |
| final runner = HotRunner( |
| <FlutterDevice>[flutterDevice], |
| target: 'main.dart', |
| debuggingOptions: DebuggingOptions.disabled(BuildInfo.debug), |
| analytics: _FakeAnalytics(), |
| ); |
| |
| await runner.run(); |
| await runner.detach(); |
| await runner.cleanupAfterSignal(); |
| expect(flutterDevice.wasExited, false); |
| }, |
| overrides: <Type, Generator>{ |
| FileSystem: () => fileSystem, |
| ProcessManager: FakeProcessManager.empty, |
| }, |
| ); |
| |
| testUsingContext( |
| 'kill on an attached device keeps the test device running', |
| () async { |
| final runner = HotRunner( |
| <FlutterDevice>[flutterDevice], |
| target: 'main.dart', |
| debuggingOptions: DebuggingOptions.disabled(BuildInfo.debug), |
| analytics: _FakeAnalytics(), |
| ); |
| |
| await runner.attach(); |
| await runner.cleanupAfterSignal(); |
| expect(flutterDevice.wasExited, false); |
| }, |
| overrides: <Type, Generator>{ |
| FileSystem: () => fileSystem, |
| ProcessManager: FakeProcessManager.empty, |
| }, |
| ); |
| }); |
| } |
| |
| class _FakeAnalytics extends Fake implements Analytics { |
| @override |
| void send(Event event) {} |
| } |
| |
| class _FakeHotRunner extends Fake implements HotRunner {} |
| |
| class _FakeDevFS extends Fake implements DevFS { |
| @override |
| final Uri? baseUri = Uri(); |
| |
| @override |
| Future<void> destroy() async {} |
| |
| @override |
| void resetLastCompiled() {} |
| } |
| |
| class _FakeFlutterDevice extends Fake implements FlutterDevice { |
| @override |
| final DevFS? devFS = _FakeDevFS(); |
| |
| @override |
| final FlutterVmService? vmService = _FakeFlutterVmService(); |
| } |
| |
| class _FakeHotCompatibleFlutterDevice extends Fake implements FlutterDevice { |
| _FakeHotCompatibleFlutterDevice(this.device); |
| |
| @override |
| final Device device; |
| |
| @override |
| DevFS? devFS = _FakeDevFS(); |
| |
| @override |
| ResidentCompiler? get generator => null; |
| |
| @override |
| Future<int> runHot({required HotRunner hotRunner, String? route}) async { |
| return 0; |
| } |
| |
| @override |
| Future<void> stopEchoingDeviceLog() async {} |
| |
| @override |
| Future<void> exitApps({Duration timeoutDelay = const Duration(seconds: 10)}) async { |
| wasExited = true; |
| } |
| |
| var wasExited = false; |
| } |
| |
| class _FakeFlutterVmService extends Fake implements FlutterVmService { |
| @override |
| final vm_service.VmService service = _FakeVmService(); |
| } |
| |
| class _FakeVmService extends Fake implements vm_service.VmService { |
| @override |
| Future<_FakeVm> getVM() async => _FakeVm(); |
| } |
| |
| class _FakeVm extends Fake implements vm_service.VM { |
| final _isolates = <vm_service.IsolateRef>[]; |
| |
| @override |
| List<vm_service.IsolateRef>? get isolates => _isolates; |
| } |