mirror of
https://github.com/flutter/flutter
synced 2024-10-13 03:32:55 +00:00
Add exception to FakeCommand (#75545)
This commit is contained in:
parent
bbc1614aa9
commit
152d88a3df
|
@ -184,19 +184,17 @@ void main() {
|
|||
});
|
||||
|
||||
testUsingContext('fetchLatestVersion throws toolExit if HEAD is detached', () async {
|
||||
processManager.addCommands(<FakeCommand>[
|
||||
const FakeCommand(command: <String>[
|
||||
processManager.addCommands(const <FakeCommand>[
|
||||
FakeCommand(command: <String>[
|
||||
'git', 'fetch', '--tags'
|
||||
]),
|
||||
FakeCommand(
|
||||
command: const <String>['git', 'rev-parse', '--verify', '@{u}'],
|
||||
onRun: () {
|
||||
throw const ProcessException(
|
||||
'git',
|
||||
<String>['rev-parse', '--verify', '@{u}'],
|
||||
'fatal: HEAD does not point to a branch',
|
||||
);
|
||||
}
|
||||
command: <String>['git', 'rev-parse', '--verify', '@{u}'],
|
||||
exception: ProcessException(
|
||||
'git',
|
||||
<String>['rev-parse', '--verify', '@{u}'],
|
||||
'fatal: HEAD does not point to a branch',
|
||||
),
|
||||
),
|
||||
]);
|
||||
|
||||
|
@ -211,19 +209,17 @@ void main() {
|
|||
});
|
||||
|
||||
testUsingContext('fetchRemoteRevision throws toolExit if no upstream configured', () async {
|
||||
processManager.addCommands(<FakeCommand>[
|
||||
const FakeCommand(command: <String>[
|
||||
processManager.addCommands(const <FakeCommand>[
|
||||
FakeCommand(command: <String>[
|
||||
'git', 'fetch', '--tags'
|
||||
]),
|
||||
FakeCommand(
|
||||
command: const <String>['git', 'rev-parse', '--verify', '@{u}'],
|
||||
onRun: () {
|
||||
throw const ProcessException(
|
||||
'git',
|
||||
<String>['rev-parse', '--verify', '@{u}'],
|
||||
'fatal: no upstream configured for branch',
|
||||
);
|
||||
},
|
||||
command: <String>['git', 'rev-parse', '--verify', '@{u}'],
|
||||
exception: ProcessException(
|
||||
'git',
|
||||
<String>['rev-parse', '--verify', '@{u}'],
|
||||
'fatal: no upstream configured for branch',
|
||||
),
|
||||
),
|
||||
]);
|
||||
|
||||
|
@ -242,18 +238,16 @@ void main() {
|
|||
testUsingContext('git exception during attemptReset throwsToolExit', () async {
|
||||
const String revision = 'abc123';
|
||||
const String errorMessage = 'fatal: Could not parse object ´$revision´';
|
||||
processManager.addCommands(<FakeCommand>[
|
||||
FakeCommand(
|
||||
command: const <String>['git', 'reset', '--hard', revision],
|
||||
onRun: () {
|
||||
throw const ProcessException(
|
||||
'git',
|
||||
<String>['reset', '--hard', revision],
|
||||
errorMessage,
|
||||
);
|
||||
},
|
||||
processManager.addCommand(
|
||||
const FakeCommand(
|
||||
command: <String>['git', 'reset', '--hard', revision],
|
||||
exception: ProcessException(
|
||||
'git',
|
||||
<String>['reset', '--hard', revision],
|
||||
errorMessage,
|
||||
),
|
||||
),
|
||||
]);
|
||||
);
|
||||
|
||||
await expectLater(
|
||||
() async => await realCommandRunner.attemptReset(revision),
|
||||
|
|
|
@ -46,14 +46,12 @@ void main() {
|
|||
});
|
||||
|
||||
testUsingContext('AndroidStudioValidator gives doctor error on java crash', () async {
|
||||
fakeProcessManager.addCommand(FakeCommand(
|
||||
command: const <String>[
|
||||
fakeProcessManager.addCommand(const FakeCommand(
|
||||
command: <String>[
|
||||
'/opt/android-studio-with-cheese-5.0/jre/bin/java',
|
||||
'-version',
|
||||
],
|
||||
onRun: () {
|
||||
throw const ProcessException('java', <String>['-version']);
|
||||
},
|
||||
exception: ProcessException('java', <String>['-version']),
|
||||
));
|
||||
const String installPath = '/opt/android-studio-with-cheese-5.0';
|
||||
const String studioHome = '$home/.AndroidStudioWithCheese5.0';
|
||||
|
|
|
@ -228,18 +228,16 @@ void main() {
|
|||
],
|
||||
stdout: 'devtools 0.9.6',
|
||||
),
|
||||
FakeCommand(
|
||||
command: const <String>[
|
||||
'pub',
|
||||
'global',
|
||||
'run',
|
||||
'devtools',
|
||||
'--no-launch-browser',
|
||||
'--vm-uri=http://127.0.0.1:1234/abcdefg',
|
||||
],
|
||||
onRun: () {
|
||||
throw const ProcessException('pub', <String>[]);
|
||||
}
|
||||
const FakeCommand(
|
||||
command: <String>[
|
||||
'pub',
|
||||
'global',
|
||||
'run',
|
||||
'devtools',
|
||||
'--no-launch-browser',
|
||||
'--vm-uri=http://127.0.0.1:1234/abcdefg',
|
||||
],
|
||||
exception: ProcessException('pub', <String>[]),
|
||||
)
|
||||
]),
|
||||
);
|
||||
|
@ -273,18 +271,16 @@ void main() {
|
|||
],
|
||||
stdout: 'devtools 0.9.6',
|
||||
),
|
||||
FakeCommand(
|
||||
command: const <String>[
|
||||
'pub',
|
||||
'global',
|
||||
'run',
|
||||
'devtools',
|
||||
'--no-launch-browser',
|
||||
'--vm-uri=http://127.0.0.1:1234/abcdefg',
|
||||
],
|
||||
onRun: () {
|
||||
throw const ProcessException('pub', <String>[]);
|
||||
}
|
||||
const FakeCommand(
|
||||
command: <String>[
|
||||
'pub',
|
||||
'global',
|
||||
'run',
|
||||
'devtools',
|
||||
'--no-launch-browser',
|
||||
'--vm-uri=http://127.0.0.1:1234/abcdefg',
|
||||
],
|
||||
exception: ProcessException('pub', <String>[]),
|
||||
)
|
||||
]),
|
||||
);
|
||||
|
|
|
@ -137,9 +137,7 @@ void main() {
|
|||
], environment: const <String, String>{
|
||||
'PATH': '/usr/bin:null',
|
||||
...kDyLdLibEntry,
|
||||
}, onRun: () {
|
||||
throw const ProcessException('ios-deploy', <String>[]);
|
||||
})
|
||||
}, exception: const ProcessException('ios-deploy', <String>[])),
|
||||
]);
|
||||
final IOSDevice device = setUpIOSDevice(processManager: processManager, artifacts: artifacts);
|
||||
final bool isAppInstalled = await device.isAppInstalled(iosApp);
|
||||
|
@ -244,9 +242,7 @@ void main() {
|
|||
], environment: const <String, String>{
|
||||
'PATH': '/usr/bin:null',
|
||||
...kDyLdLibEntry,
|
||||
}, onRun: () {
|
||||
throw const ProcessException('ios-deploy', <String>[]);
|
||||
})
|
||||
}, exception: const ProcessException('ios-deploy', <String>[])),
|
||||
]);
|
||||
final IOSDevice device = setUpIOSDevice(processManager: processManager, artifacts: artifacts);
|
||||
final bool wasAppInstalled = await device.installApp(iosApp);
|
||||
|
@ -267,9 +263,7 @@ void main() {
|
|||
], environment: const <String, String>{
|
||||
'PATH': '/usr/bin:null',
|
||||
...kDyLdLibEntry,
|
||||
}, onRun: () {
|
||||
throw const ProcessException('ios-deploy', <String>[]);
|
||||
})
|
||||
}, exception: const ProcessException('ios-deploy', <String>[])),
|
||||
]);
|
||||
final IOSDevice device = setUpIOSDevice(processManager: processManager, artifacts: artifacts);
|
||||
final bool wasAppUninstalled = await device.uninstallApp(iosApp);
|
||||
|
|
|
@ -799,17 +799,15 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
|
|||
});
|
||||
|
||||
testWithoutContext('.install() handles exceptions', () async {
|
||||
fakeProcessManager.addCommand(FakeCommand(
|
||||
command: const <String>[
|
||||
fakeProcessManager.addCommand(const FakeCommand(
|
||||
command: <String>[
|
||||
'xcrun',
|
||||
'simctl',
|
||||
'install',
|
||||
deviceId,
|
||||
appId,
|
||||
],
|
||||
onRun: () {
|
||||
throw const ProcessException('xcrun', <String>[]);
|
||||
},
|
||||
exception: ProcessException('xcrun', <String>[]),
|
||||
));
|
||||
|
||||
expect(
|
||||
|
@ -819,17 +817,15 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
|
|||
});
|
||||
|
||||
testWithoutContext('.uninstall() handles exceptions', () async {
|
||||
fakeProcessManager.addCommand(FakeCommand(
|
||||
command: const <String>[
|
||||
fakeProcessManager.addCommand(const FakeCommand(
|
||||
command: <String>[
|
||||
'xcrun',
|
||||
'simctl',
|
||||
'uninstall',
|
||||
deviceId,
|
||||
appId,
|
||||
],
|
||||
onRun: () {
|
||||
throw const ProcessException('xcrun', <String>[]);
|
||||
},
|
||||
exception: ProcessException('xcrun', <String>[]),
|
||||
));
|
||||
|
||||
expect(
|
||||
|
@ -839,17 +835,15 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
|
|||
});
|
||||
|
||||
testWithoutContext('.launch() handles exceptions', () async {
|
||||
fakeProcessManager.addCommand(FakeCommand(
|
||||
command: const <String>[
|
||||
fakeProcessManager.addCommand(const FakeCommand(
|
||||
command: <String>[
|
||||
'xcrun',
|
||||
'simctl',
|
||||
'launch',
|
||||
deviceId,
|
||||
appId,
|
||||
],
|
||||
onRun: () {
|
||||
throw const ProcessException('xcrun', <String>[]);
|
||||
},
|
||||
exception: ProcessException('xcrun', <String>[]),
|
||||
));
|
||||
|
||||
expect(
|
||||
|
|
|
@ -50,18 +50,6 @@ void main() {
|
|||
);
|
||||
});
|
||||
|
||||
// Work around https://github.com/flutter/flutter/issues/56415.
|
||||
testWithoutContext('xcodebuild versionText returns null when xcodebuild is not installed', () {
|
||||
when(processManager.runSync(<String>['which', 'sysctl']))
|
||||
.thenReturn(ProcessResult(0, 0, '', ''));
|
||||
when(processManager.runSync(<String>['sysctl', 'hw.optional.arm64']))
|
||||
.thenReturn(ProcessResult(0, 1, '', ''));
|
||||
when(processManager.runSync(<String>['xcrun', 'xcodebuild', '-version']))
|
||||
.thenThrow(const ProcessException(xcodebuild, <String>['-version']));
|
||||
|
||||
expect(xcodeProjectInterpreter.versionText, isNull);
|
||||
});
|
||||
|
||||
testWithoutContext('xcodebuild build settings flakes', () async {
|
||||
const Duration delay = Duration(seconds: 1);
|
||||
processManager.processFactory = mocks.flakyProcessFactory(
|
||||
|
@ -143,6 +131,19 @@ void main() {
|
|||
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
|
||||
});
|
||||
|
||||
testWithoutContext('xcodebuild versionText returns null when xcodebuild is not installed', () {
|
||||
fakeProcessManager.addCommands(const <FakeCommand>[
|
||||
kWhichSysctlCommand,
|
||||
kARMCheckCommand,
|
||||
FakeCommand(
|
||||
command: <String>['xcrun', 'xcodebuild', '-version'],
|
||||
exception: ProcessException(xcodebuild, <String>['-version']),
|
||||
),
|
||||
]);
|
||||
|
||||
expect(xcodeProjectInterpreter.versionText, isNull);
|
||||
});
|
||||
|
||||
testWithoutContext('xcodebuild versionText returns formatted version text', () {
|
||||
fakeProcessManager.addCommands(const <FakeCommand>[
|
||||
kWhichSysctlCommand,
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter_tools/src/artifacts.dart';
|
||||
import 'package:flutter_tools/src/base/io.dart' show ProcessException, ProcessResult;
|
||||
import 'package:flutter_tools/src/base/io.dart' show ProcessException;
|
||||
import 'package:flutter_tools/src/base/logger.dart';
|
||||
import 'package:flutter_tools/src/base/platform.dart';
|
||||
import 'package:flutter_tools/src/build_info.dart';
|
||||
|
@ -29,89 +29,6 @@ void main() {
|
|||
logger = BufferLogger.test();
|
||||
});
|
||||
|
||||
// Group exists to work around https://github.com/flutter/flutter/issues/56415.
|
||||
// Do not add more `MockProcessManager` tests.
|
||||
group('MockProcessManager', () {
|
||||
ProcessManager processManager;
|
||||
|
||||
setUp(() {
|
||||
processManager = MockProcessManager();
|
||||
});
|
||||
|
||||
group('Xcode', () {
|
||||
Xcode xcode;
|
||||
MockXcodeProjectInterpreter mockXcodeProjectInterpreter;
|
||||
|
||||
setUp(() {
|
||||
mockXcodeProjectInterpreter = MockXcodeProjectInterpreter();
|
||||
xcode = Xcode.test(
|
||||
processManager: processManager,
|
||||
xcodeProjectInterpreter: mockXcodeProjectInterpreter,
|
||||
);
|
||||
});
|
||||
|
||||
testWithoutContext('xcodeSelectPath returns null when xcode-select is not installed', () {
|
||||
when(processManager.runSync(<String>['/usr/bin/xcode-select', '--print-path']))
|
||||
.thenThrow(const ProcessException('/usr/bin/xcode-select', <String>['--print-path']));
|
||||
expect(xcode.xcodeSelectPath, isNull);
|
||||
when(processManager.runSync(<String>['/usr/bin/xcode-select', '--print-path']))
|
||||
.thenThrow(ArgumentError('Invalid argument(s): Cannot find executable for /usr/bin/xcode-select'));
|
||||
|
||||
expect(xcode.xcodeSelectPath, isNull);
|
||||
});
|
||||
|
||||
testWithoutContext('eulaSigned is false when clang is not installed', () {
|
||||
when(mockXcodeProjectInterpreter.xcrunCommand()).thenReturn(<String>['xcrun']);
|
||||
|
||||
when(processManager.runSync(<String>['which', 'sysctl']))
|
||||
.thenReturn(ProcessResult(1, 0, '', ''));
|
||||
when(processManager.runSync(<String>['sysctl', 'hw.optional.arm64']))
|
||||
.thenReturn(ProcessResult(123, 1, '', ''));
|
||||
when(processManager.runSync(<String>['xcrun', 'clang']))
|
||||
.thenThrow(const ProcessException('xcrun', <String>['clang']));
|
||||
|
||||
expect(xcode.eulaSigned, isFalse);
|
||||
});
|
||||
});
|
||||
|
||||
group('xcdevice', () {
|
||||
XCDevice xcdevice;
|
||||
Xcode xcode;
|
||||
|
||||
setUp(() {
|
||||
xcode = Xcode.test(
|
||||
processManager: FakeProcessManager.any(),
|
||||
xcodeProjectInterpreter: XcodeProjectInterpreter.test(
|
||||
processManager: FakeProcessManager.any(),
|
||||
),
|
||||
);
|
||||
xcdevice = XCDevice(
|
||||
processManager: processManager,
|
||||
logger: logger,
|
||||
xcode: xcode,
|
||||
platform: null,
|
||||
artifacts: Artifacts.test(),
|
||||
cache: Cache.test(),
|
||||
iproxy: IProxy.test(logger: logger, processManager: processManager),
|
||||
);
|
||||
});
|
||||
|
||||
testWithoutContext('available devices xcdevice fails', () async {
|
||||
when(processManager.run(<String>['xcrun', 'xcdevice', 'list', '--timeout', '2']))
|
||||
.thenThrow(const ProcessException('xcrun', <String>['xcdevice', 'list', '--timeout', '2']));
|
||||
|
||||
expect(await xcdevice.getAvailableIOSDevices(), isEmpty);
|
||||
});
|
||||
|
||||
testWithoutContext('diagnostics xcdevice fails', () async {
|
||||
when(processManager.run(<String>['xcrun', 'xcdevice', 'list', '--timeout', '2']))
|
||||
.thenThrow(const ProcessException('xcrun', <String>['xcdevice', 'list', '--timeout', '2']));
|
||||
|
||||
expect(await xcdevice.getDiagnostics(), isEmpty);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
group('FakeProcessManager', () {
|
||||
FakeProcessManager fakeProcessManager;
|
||||
|
||||
|
@ -200,6 +117,24 @@ void main() {
|
|||
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
|
||||
});
|
||||
|
||||
testWithoutContext('xcodeSelectPath returns null when xcode-select is not installed', () {
|
||||
fakeProcessManager.addCommand(const FakeCommand(
|
||||
command: <String>['/usr/bin/xcode-select', '--print-path'],
|
||||
exception: ProcessException('/usr/bin/xcode-select', <String>['--print-path']),
|
||||
));
|
||||
|
||||
expect(xcode.xcodeSelectPath, isNull);
|
||||
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
|
||||
|
||||
fakeProcessManager.addCommand(FakeCommand(
|
||||
command: const <String>['/usr/bin/xcode-select', '--print-path'],
|
||||
exception: ArgumentError('Invalid argument(s): Cannot find executable for /usr/bin/xcode-select'),
|
||||
));
|
||||
|
||||
expect(xcode.xcodeSelectPath, isNull);
|
||||
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
|
||||
});
|
||||
|
||||
testWithoutContext('xcodeVersionSatisfactory is false when version is less than minimum', () {
|
||||
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
|
||||
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(9);
|
||||
|
@ -343,6 +278,18 @@ void main() {
|
|||
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
|
||||
});
|
||||
|
||||
testWithoutContext('eulaSigned is false when clang is not installed', () {
|
||||
when(mockXcodeProjectInterpreter.xcrunCommand()).thenReturn(<String>['xcrun']);
|
||||
fakeProcessManager.addCommand(
|
||||
const FakeCommand(
|
||||
command: <String>['xcrun', 'clang'],
|
||||
exception: ProcessException('xcrun', <String>['clang']),
|
||||
),
|
||||
);
|
||||
|
||||
expect(xcode.eulaSigned, isFalse);
|
||||
});
|
||||
|
||||
testWithoutContext('eulaSigned is true when clang output indicates EULA has been accepted', () {
|
||||
fakeProcessManager.addCommands(
|
||||
const <FakeCommand>[
|
||||
|
@ -609,6 +556,15 @@ void main() {
|
|||
Artifacts: () => Artifacts.test(),
|
||||
});
|
||||
|
||||
testWithoutContext('available devices xcdevice fails', () async {
|
||||
fakeProcessManager.addCommand(const FakeCommand(
|
||||
command: <String>['xcrun', 'xcdevice', 'list', '--timeout', '2'],
|
||||
exception: ProcessException('xcrun', <String>['xcdevice', 'list', '--timeout', '2']),
|
||||
));
|
||||
|
||||
expect(await xcdevice.getAvailableIOSDevices(), isEmpty);
|
||||
});
|
||||
|
||||
testWithoutContext('uses timeout', () async {
|
||||
fakeProcessManager.addCommand(const FakeCommand(
|
||||
command: <String>['xcrun', 'xcdevice', 'list', '--timeout', '20'],
|
||||
|
@ -737,6 +693,15 @@ void main() {
|
|||
Platform: () => macPlatform,
|
||||
});
|
||||
|
||||
testWithoutContext('diagnostics xcdevice fails', () async {
|
||||
fakeProcessManager.addCommand(const FakeCommand(
|
||||
command: <String>['xcrun', 'xcdevice', 'list', '--timeout', '2'],
|
||||
exception: ProcessException('xcrun', <String>['xcdevice', 'list', '--timeout', '2']),
|
||||
));
|
||||
|
||||
expect(await xcdevice.getDiagnostics(), isEmpty);
|
||||
});
|
||||
|
||||
testUsingContext('returns error message', () async {
|
||||
const String devicesOutput = '''
|
||||
[
|
||||
|
@ -843,5 +808,4 @@ void main() {
|
|||
});
|
||||
}
|
||||
|
||||
class MockProcessManager extends Mock implements ProcessManager {}
|
||||
class MockXcodeProjectInterpreter extends Mock implements XcodeProjectInterpreter {}
|
||||
|
|
|
@ -33,6 +33,7 @@ class FakeCommand {
|
|||
this.stderr = '',
|
||||
this.completer,
|
||||
this.stdin,
|
||||
this.exception,
|
||||
}) : assert(command != null),
|
||||
assert(duration != null),
|
||||
assert(exitCode != null);
|
||||
|
@ -97,6 +98,9 @@ class FakeCommand {
|
|||
/// [FakeProcess].
|
||||
final IOSink stdin;
|
||||
|
||||
/// If provided, this exception will be thrown when the fake command is run.
|
||||
final dynamic exception;
|
||||
|
||||
void _matches(
|
||||
List<String> command,
|
||||
String workingDirectory,
|
||||
|
@ -229,6 +233,9 @@ abstract class FakeProcessManager implements ProcessManager {
|
|||
) {
|
||||
_pid += 1;
|
||||
final FakeCommand fakeCommand = findCommand(command, workingDirectory, environment, encoding);
|
||||
if (fakeCommand.exception != null) {
|
||||
throw fakeCommand.exception;
|
||||
}
|
||||
if (fakeCommand.onRun != null) {
|
||||
fakeCommand.onRun();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue