Unverified Commit 613a9598 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

only use code single path for verification of target file existence (#70962)

parent ffe5197e
......@@ -211,6 +211,7 @@ known, it can be explicitly provided to attach via the command-line, e.g.
Future<void> _attachToDevice(Device device) async {
final FlutterProject flutterProject = FlutterProject.current();
Future<int> getDevicePort() async {
if (debugPort != null) {
return debugPort;
......@@ -388,7 +389,7 @@ known, it can be explicitly provided to attach via the command-line, e.g.
device,
fileSystemRoots: stringsArg('filesystem-root'),
fileSystemScheme: stringArg('filesystem-scheme'),
target: stringArg('target'),
target: targetFile,
targetModel: TargetModel(stringArg('target-model')),
buildInfo: buildInfo,
userIdentifier: userIdentifier,
......
......@@ -447,6 +447,7 @@ class RunCommand extends RunCommandBase {
// debug mode.
final BuildInfo buildInfo = await getBuildInfo();
final bool hotMode = shouldUseHotMode(buildInfo);
final String applicationBinaryPath = stringArg('use-application-binary');
writePidFile(stringArg('pid-file'));
......@@ -464,7 +465,6 @@ class RunCommand extends RunCommandBase {
);
AppInstance app;
try {
final String applicationBinaryPath = stringArg('use-application-binary');
app = await daemon.appDomain.startApp(
devices.first, globals.fs.currentDirectory.path, targetFile, route,
await createDebuggingOptions(), hotMode,
......@@ -535,7 +535,7 @@ class RunCommand extends RunCommandBase {
fileSystemRoots: stringsArg('filesystem-root'),
fileSystemScheme: stringArg('filesystem-scheme'),
experimentalFlags: expFlags,
target: stringArg('target'),
target: targetFile,
buildInfo: buildInfo,
userIdentifier: userIdentifier,
platform: globals.platform,
......@@ -548,7 +548,6 @@ class RunCommand extends RunCommandBase {
await devices.single.targetPlatform == TargetPlatform.web_javascript;
ResidentRunner runner;
final String applicationBinaryPath = stringArg('use-application-binary');
if (hotMode && !webMode) {
runner = HotRunner(
flutterDevices,
......
......@@ -468,16 +468,6 @@ class _ResidentWebRunner extends ResidentWebRunner {
globals.printStatus('This application is not configured to build on the web.');
globals.printStatus('To add web support to a project, run `flutter create .`.');
}
if (!globals.fs.isFileSync(mainPath)) {
String message = 'Tried to run $mainPath, but that file does not exist.';
if (target == null) {
message +=
'\nConsider using the -t option to specify the Dart file to start.';
}
globals.printError(message);
appFailedToStart();
return 1;
}
final String modeName = debuggingOptions.buildInfo.friendlyModeName;
globals.printStatus(
'Launching ${globals.fsUtils.getDisplayPath(target)} '
......
......@@ -712,7 +712,7 @@ class FlutterDevice {
abstract class ResidentRunner {
ResidentRunner(
this.flutterDevices, {
this.target,
@required this.target,
@required this.debuggingOptions,
String projectRootPath,
this.ipv6,
......@@ -720,7 +720,7 @@ abstract class ResidentRunner {
this.hotMode = true,
String dillOutputPath,
this.machine = false,
}) : mainPath = findMainDartFile(target),
}) : mainPath = globals.fs.path.absolute(target),
packagesFilePath = debuggingOptions.buildInfo.packagesPath,
projectRootPath = projectRootPath ?? globals.fs.currentDirectory.path,
_dillOutputPath = dillOutputPath,
......@@ -1367,17 +1367,6 @@ class OperationResult {
static final OperationResult ok = OperationResult(0, '');
}
/// Given the value of the --target option, return the path of the Dart file
/// where the app's main function should be.
String findMainDartFile([ String target ]) {
target ??= '';
final String targetPath = globals.fs.path.absolute(target);
if (globals.fs.isDirectorySync(targetPath)) {
return globals.fs.path.join(targetPath, 'lib', 'main.dart');
}
return targetPath;
}
Future<String> getMissingPackageHintForPlatform(TargetPlatform platform) async {
switch (platform) {
case TargetPlatform.android_arm:
......
......@@ -17,7 +17,7 @@ import 'vmservice.dart';
class ColdRunner extends ResidentRunner {
ColdRunner(
List<FlutterDevice> devices, {
String target,
@required String target,
@required DebuggingOptions debuggingOptions,
this.traceStartup = false,
this.awaitFirstFrameWhenTracing = true,
......@@ -52,18 +52,6 @@ class ColdRunner extends ResidentRunner {
Completer<void> appStartedCompleter,
String route,
}) async {
final bool prebuiltMode = applicationBinary != null;
if (!prebuiltMode) {
if (!globals.fs.isFileSync(mainPath)) {
String message = 'Tried to run $mainPath, but that file does not exist.';
if (target == null) {
message += '\nConsider using the -t option to specify the Dart file to start.';
}
globals.printError(message);
return 1;
}
}
try {
for (final FlutterDevice device in flutterDevices) {
final int result = await device.runCold(
......
......@@ -66,7 +66,7 @@ class DeviceReloadReport {
class HotRunner extends ResidentRunner {
HotRunner(
List<FlutterDevice> devices, {
String target,
@required String target,
@required DebuggingOptions debuggingOptions,
this.benchmarkMode = false,
this.applicationBinary,
......@@ -295,15 +295,6 @@ class HotRunner extends ResidentRunner {
Completer<void> appStartedCompleter,
String route,
}) async {
if (!globals.fs.isFileSync(mainPath)) {
String message = 'Tried to run $mainPath, but that file does not exist.';
if (target == null) {
message += '\nConsider using the -t option to specify the Dart file to start.';
}
globals.printError(message);
return 1;
}
firstBuildTime = DateTime.now();
final List<Future<bool>> startupTasks = <Future<bool>>[];
......
......@@ -39,6 +39,7 @@ void main() {
final int exitCode = await ColdRunner(devices,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
target: 'main.dart',
).attach();
expect(exitCode, 2);
});
......@@ -61,6 +62,7 @@ void main() {
await ColdRunner(devices,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
target: 'main.dart',
).cleanupAtFinish();
verify(mockDevice1.dispose());
......@@ -71,21 +73,6 @@ void main() {
});
group('cold run', () {
testUsingContext('returns 1 if not prebuilt mode & mainPath does not exist', () async {
final MockDevice mockDevice = MockDevice();
final MockFlutterDevice mockFlutterDevice = MockFlutterDevice();
when(mockFlutterDevice.device).thenReturn(mockDevice);
final List<FlutterDevice> devices = <FlutterDevice>[mockFlutterDevice];
final int result = await ColdRunner(
devices,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.debug),
).run();
expect(result, 1);
expect(testLogger.errorText, matches(r'Tried to run .*, but that file does not exist\.'));
expect(testLogger.errorText, matches(r'Consider using the -t option to specify the Dart file to start\.'));
});
testUsingContext('calls runCold on attached device', () async {
final MockDevice mockDevice = MockDevice();
final MockFlutterDevice mockFlutterDevice = MockFlutterDevice();
......@@ -100,6 +87,7 @@ void main() {
devices,
applicationBinary: applicationBinary,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
target: 'main.dart',
).run();
expect(result, 1);
......
......@@ -184,6 +184,7 @@ void main() {
final OperationResult result = await HotRunner(
devices,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.debug),
target: 'main.dart',
).restart(fullRestart: true);
// Expect hot restart failed.
expect(result.isOk, false);
......@@ -214,7 +215,8 @@ void main() {
];
final OperationResult result = await HotRunner(
devices,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.debug)
debuggingOptions: DebuggingOptions.disabled(BuildInfo.debug),
target: 'main.dart',
).restart(fullRestart: true);
// Expect hot restart failed.
expect(result.isOk, false);
......@@ -317,6 +319,7 @@ void main() {
final HotRunner hotRunner = HotRunner(
devices,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.debug),
target: 'main.dart',
);
final OperationResult result = await hotRunner.restart(fullRestart: true);
// Expect hot restart was successful.
......@@ -345,6 +348,7 @@ void main() {
final OperationResult result = await HotRunner(
devices,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.debug),
target: 'main.dart',
).restart(fullRestart: true);
expect(result.isOk, false);
expect(result.message, 'setupHotRestart failed');
......@@ -410,6 +414,7 @@ void main() {
final HotRunner hotRunner = HotRunner(
devices,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.debug),
target: 'main.dart',
);
final OperationResult result = await hotRunner.restart(fullRestart: true);
// Expect hot restart successful.
......@@ -446,7 +451,8 @@ void main() {
];
await HotRunner(
devices,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.debug)
debuggingOptions: DebuggingOptions.disabled(BuildInfo.debug),
target: 'main.dart',
).cleanupAfterSignal();
expect(shutdownTestingConfig.shutdownHookCalled, true);
}, overrides: <Type, Generator>{
......@@ -470,7 +476,8 @@ void main() {
];
await HotRunner(
devices,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.debug)
debuggingOptions: DebuggingOptions.disabled(BuildInfo.debug),
target: 'main.dart',
).preExit();
expect(shutdownTestingConfig.shutdownHookCalled, true);
}, overrides: <Type, Generator>{
......@@ -514,6 +521,7 @@ void main() {
final int exitCode = await HotRunner(devices,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
target: 'main.dart',
).attach();
expect(exitCode, 2);
}, overrides: <Type, Generator>{
......@@ -546,6 +554,7 @@ void main() {
await HotRunner(devices,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
target: 'main.dart',
).cleanupAtFinish();
verify(mockDevice1.dispose());
......
......@@ -151,6 +151,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
target: 'main.dart',
);
});
mockFlutterDevice = MockFlutterDevice();
......@@ -244,6 +245,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
target: 'main.dart',
);
when(mockFlutterDevice.generator).thenReturn(residentCompiler);
when(residentCompiler.recompile(
......@@ -285,6 +287,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
target: 'main.dart',
);
when(mockFlutterDevice.generator).thenReturn(residentCompiler);
when(residentCompiler.recompile(
......@@ -319,6 +322,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.release),
target: 'main.dart',
);
when(mockFlutterDevice.runCold(
coldRunner: anyNamed('coldRunner'),
......@@ -343,6 +347,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.release),
target: 'main.dart',
);
when(mockFlutterDevice.runCold(
coldRunner: anyNamed('coldRunner'),
......@@ -372,6 +377,7 @@ void main() {
applicationBinary: globals.fs.file('app.apk'),
stayResident: false,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
target: 'main.dart',
);
when(mockFlutterDevice.generator).thenReturn(residentCompiler);
when(residentCompiler.recompile(
......@@ -461,6 +467,7 @@ void main() {
fastStart: true,
startPaused: true,
),
target: 'main.dart',
);
final Completer<DebugConnectionInfo> onConnectionInfo = Completer<DebugConnectionInfo>.sync();
final Completer<void> onAppStart = Completer<void>.sync();
......@@ -599,6 +606,7 @@ void main() {
mockFlutterDevice,
],
stayResident: false,
target: 'main.dart',
debuggingOptions: DebuggingOptions.enabled(const BuildInfo(
BuildMode.debug, '', treeShakeIcons: false, extraFrontEndOptions: <String>[
'--enable-experiment=non-nullable',
......@@ -677,6 +685,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
target: 'main.dart',
);
when(mockDevice.sdkNameAndVersion).thenAnswer((Invocation invocation) async {
return 'Example';
......@@ -1017,6 +1026,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
target: 'main.dart',
);
when(mockDevice.sdkNameAndVersion).thenAnswer((Invocation invocation) async {
return 'Example';
......@@ -1416,6 +1426,7 @@ void main() {
stayResident: false,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
dillOutputPath: globals.fs.path.join('foobar', 'app.dill'),
target: 'main.dart',
);
expect(otherRunner.artifactDirectory.path, contains('foobar'));
}));
......@@ -1526,6 +1537,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
target: 'main.dart',
);
residentRunner.printHelp(details: true);
......@@ -1663,6 +1675,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
target: 'main.dart',
);
await residentRunner.screenshot(mockFlutterDevice);
......@@ -1769,6 +1782,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
target: 'main.dart',
);
when(mockDevice.supportsScreenshot).thenReturn(true);
when(mockDevice.takeScreenshot(any))
......@@ -1917,6 +1931,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
target: 'main.dart',
);
expect(await residentRunner.debugDumpApp(), false);
......@@ -1938,6 +1953,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
target: 'main.dart',
);
expect(await residentRunner.debugDumpRenderTree(), false);
......@@ -1959,6 +1975,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
target: 'main.dart',
);
expect(await residentRunner.debugDumpLayerTree(), false);
......@@ -1980,6 +1997,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
target: 'main.dart',
);
expect(await residentRunner.debugDumpSemanticsTreeInTraversalOrder(), false);
......@@ -2001,6 +2019,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
target: 'main.dart',
);
expect(await residentRunner.debugDumpSemanticsTreeInInverseHitTestOrder(), false);
......@@ -2022,6 +2041,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
target: 'main.dart',
);
expect(await residentRunner.debugToggleDebugPaintSizeEnabled(), false);
......@@ -2043,6 +2063,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
target: 'main.dart',
);
expect(await residentRunner.debugToggleBrightness(), false);
......@@ -2087,6 +2108,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
target: 'main.dart',
);
expect(await residentRunner.debugToggleInvertOversizedImages(), false);
......@@ -2101,6 +2123,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile),
target: 'main.dart',
);
expect(await residentRunner.debugToggleInvertOversizedImages(), false);
......@@ -2145,6 +2168,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
target: 'main.dart',
);
expect(await residentRunner.debugToggleDebugCheckElevationsEnabled(), false);
......@@ -2166,6 +2190,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
target: 'main.dart',
);
expect(await residentRunner.debugTogglePerformanceOverlayOverride(), false);
......@@ -2188,6 +2213,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
target: 'main.dart',
);
expect(await residentRunner.debugToggleWidgetInspector(), false);
......@@ -2209,6 +2235,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
target: 'main.dart',
);
expect(await residentRunner.debugToggleProfileWidgetBuilds(), false);
......@@ -2229,6 +2256,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug, vmserviceOutFile: 'foo'),
target: 'main.dart',
);
when(mockFlutterDevice.runHot(
hotRunner: anyNamed('hotRunner'),
......@@ -2255,6 +2283,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
target: 'main.dart',
);
residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC');
when(mockFlutterDevice.runHot(
......@@ -2289,6 +2318,7 @@ void main() {
dartDefines: <String>['a', 'b'],
)
),
target: 'main.dart',
);
residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC');
when(mockFlutterDevice.runHot(
......@@ -2324,6 +2354,7 @@ void main() {
extraFrontEndOptions: <String>['--enable-experiment=non-nullable>']
)
),
target: 'main.dart',
);
residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC');
when(mockFlutterDevice.runHot(
......@@ -2353,6 +2384,7 @@ void main() {
stayResident: false,
dillOutputPath: 'test',
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
target: 'main.dart',
);
residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC');
when(mockFlutterDevice.runHot(
......@@ -2385,6 +2417,7 @@ void main() {
treeShakeIcons: false,
trackWidgetCreation: true,
)),
target: 'main.dart',
);
residentRunner.artifactDirectory.childFile('app.dill').writeAsStringSync('ABC');
when(mockFlutterDevice.runHot(
......@@ -2413,6 +2446,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
target: 'main.dart',
);
when(mockFlutterDevice.runHot(
hotRunner: anyNamed('hotRunner'),
......@@ -2443,6 +2477,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug, vmserviceOutFile: 'foo'),
target: 'main.dart',
);
when(mockFlutterDevice.runHot(
hotRunner: anyNamed('hotRunner'),
......@@ -2471,6 +2506,7 @@ void main() {
],
stayResident: false,
debuggingOptions: DebuggingOptions.enabled(BuildInfo.profile, vmserviceOutFile: 'foo'),
target: 'main.dart',
);
when(mockFlutterDevice.runCold(
coldRunner: anyNamed('coldRunner'),
......
......@@ -248,33 +248,6 @@ void main() {
Platform: () => FakePlatform(operatingSystem: 'linux', environment: <String, String>{}),
});
testUsingContext('Exits on run if target file does not exist', () async {
fileSystem.file('.packages')
..createSync(recursive: true)
..writeAsStringSync('\n');
final ResidentRunner residentWebRunner = DwdsWebRunnerFactory().createWebRunner(
mockFlutterDevice,
flutterProject: FlutterProject.current(),
debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug),
ipv6: true,
stayResident: true,
urlTunneller: null,
) as ResidentWebRunner;
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
fileSystem.file('pubspec.yaml').createSync();
fileSystem.file(fileSystem.path.join('web', 'index.html'))
.createSync(recursive: true);
expect(await residentWebRunner.run(), 1);
final String absoluteMain = fileSystem.path.absolute(fileSystem.path.join('lib', 'main.dart'));
expect(testLogger.errorText, contains('Tried to run $absoluteMain, but that file does not exist.'));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => processManager,
Pub: () => MockPub(),
Platform: () => FakePlatform(operatingSystem: 'linux', environment: <String, String>{}),
});
testUsingContext('Can successfully run and connect to vmservice', () async {
fileSystem.file('.packages')
..createSync(recursive: true)
......
......@@ -6,8 +6,10 @@ import 'dart:async';
import 'dart:io' as io;
import 'package:args/command_runner.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/error_handling_io.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/signals.dart';
import 'package:flutter_tools/src/base/time.dart';
......@@ -106,6 +108,40 @@ void main() {
await flutterCommand.run();
});
testUsingContext('finds the target file with default values', () async {
globals.fs.file('lib/main.dart').createSync(recursive: true);
final FakeTargetCommand fakeTargetCommand = FakeTargetCommand();
final CommandRunner<void> runner = createTestCommandRunner(fakeTargetCommand);
await runner.run(<String>['test']);
expect(fakeTargetCommand.cachedTargetFile, 'lib/main.dart');
}, overrides: <Type, Generator>{
FileSystem: () => MemoryFileSystem.test(),
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('finds the target file with specified value', () async {
globals.fs.file('lib/foo.dart').createSync(recursive: true);
final FakeTargetCommand fakeTargetCommand = FakeTargetCommand();
final CommandRunner<void> runner = createTestCommandRunner(fakeTargetCommand);
await runner.run(<String>['test', '-t', 'lib/foo.dart']);
expect(fakeTargetCommand.cachedTargetFile, 'lib/foo.dart');
}, overrides: <Type, Generator>{
FileSystem: () => MemoryFileSystem.test(),
ProcessManager: () => FakeProcessManager.any(),
});
testUsingContext('throws tool exit if specified file does not exist', () async {
final FakeTargetCommand fakeTargetCommand = FakeTargetCommand();
final CommandRunner<void> runner = createTestCommandRunner(fakeTargetCommand);
expect(() async => await runner.run(<String>['test', '-t', 'lib/foo.dart']), throwsToolExit());
}, overrides: <Type, Generator>{
FileSystem: () => MemoryFileSystem.test(),
ProcessManager: () => FakeProcessManager.any(),
});
void testUsingCommandContext(String testName, dynamic Function() testBody) {
testUsingContext(testName, testBody, overrides: <Type, Generator>{
ProcessInfo: () => mockProcessInfo,
......@@ -485,6 +521,26 @@ class FakeNullSafeCommand extends FlutterCommand {
}
}
class FakeTargetCommand extends FlutterCommand {
FakeTargetCommand() {
usesTargetOption();
}
@override
Future<FlutterCommandResult> runCommand() async {
cachedTargetFile = targetFile;
return FlutterCommandResult.success();
}
String cachedTargetFile;
@override
String get description => '';
@override
String get name => 'test';
}
class MockVersion extends Mock implements FlutterVersion {}
class MockProcessInfo extends Mock implements ProcessInfo {}
class MockIoProcessSignal extends Mock implements io.ProcessSignal {}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment