Unverified Commit fe921211 authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Replace MockXcode with Xcode.test in more unit tests (#74827)

parent 91437a06
......@@ -19,20 +19,24 @@ import '../../src/context.dart';
void main() {
group('clean command', () {
MockXcode mockXcode;
Xcode xcode;
MockXcodeProjectInterpreter mockXcodeProjectInterpreter;
setUp(() {
mockXcode = MockXcode();
mockXcodeProjectInterpreter = MockXcodeProjectInterpreter();
xcode = Xcode.test(
processManager: FakeProcessManager.any(),
xcodeProjectInterpreter: mockXcodeProjectInterpreter,
);
});
group('general', () {
MemoryFileSystem fs;
MockXcodeProjectInterpreter mockXcodeProjectInterpreter;
Directory buildDirectory;
FlutterProject projectUnderTest;
setUp(() {
fs = MemoryFileSystem.test();
mockXcodeProjectInterpreter = MockXcodeProjectInterpreter();
final Directory currentDirectory = fs.currentDirectory;
buildDirectory = currentDirectory.childDirectory('build');
......@@ -61,7 +65,9 @@ void main() {
});
testUsingContext('$CleanCommand removes build and .dart_tool and ephemeral directories, cleans Xcode', () async {
when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
// Xcode is installed and version satisfactory.
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(1000);
await CleanCommand().runCommand();
expect(buildDirectory.existsSync(), isFalse);
......@@ -87,31 +93,33 @@ void main() {
}, overrides: <Type, Generator>{
FileSystem: () => fs,
ProcessManager: () => FakeProcessManager.any(),
Xcode: () => mockXcode,
Xcode: () => xcode,
XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
});
testUsingContext('$CleanCommand cleans Xcode verbosely', () async {
when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
// Xcode is installed and version satisfactory.
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(1000);
await CleanCommand(verbose: true).runCommand();
verify(mockXcodeProjectInterpreter.cleanWorkspace(any, 'Runner', verbose: true)).called(2);
}, overrides: <Type, Generator>{
FileSystem: () => fs,
ProcessManager: () => FakeProcessManager.any(),
Xcode: () => mockXcode,
Xcode: () => xcode,
XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
});
});
group('Windows', () {
MockPlatform windowsPlatform;
FakePlatform windowsPlatform;
setUp(() {
windowsPlatform = MockPlatform();
windowsPlatform = FakePlatform(operatingSystem: 'windows');
});
testUsingContext('$CleanCommand prints a helpful error message on Windows', () async {
when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(false);
when(windowsPlatform.isWindows).thenReturn(true);
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(false);
final MockFile mockFile = MockFile();
when(mockFile.existsSync()).thenReturn(true);
......@@ -123,11 +131,11 @@ void main() {
verify(mockFile.deleteSync(recursive: true)).called(1);
}, overrides: <Type, Generator>{
Platform: () => windowsPlatform,
Xcode: () => mockXcode,
Xcode: () => xcode,
});
testUsingContext('$CleanCommand handles missing permissions;', () async {
when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(false);
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(false);
final MockFile mockFile = MockFile();
when(mockFile.existsSync()).thenThrow(const FileSystemException('OS error: Access Denied'));
......@@ -139,15 +147,13 @@ void main() {
verifyNever(mockFile.deleteSync(recursive: true));
}, overrides: <Type, Generator>{
Platform: () => windowsPlatform,
Xcode: () => mockXcode,
Xcode: () => xcode,
});
});
});
}
class MockFile extends Mock implements File {}
class MockPlatform extends Mock implements Platform {}
class MockXcode extends Mock implements Xcode {}
class MockXcodeProjectInterpreter extends Mock implements XcodeProjectInterpreter {
@override
......
......@@ -6,12 +6,8 @@ import 'package:file/memory.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/build.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/terminal.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/ios/xcodeproj.dart';
import 'package:flutter_tools/src/macos/xcode.dart';
import 'package:flutter_tools/src/reporting/reporting.dart';
import '../../src/common.dart';
import '../../src/context.dart';
......@@ -185,30 +181,16 @@ void main() {
AOTSnapshotter snapshotter;
Artifacts artifacts;
FakeProcessManager processManager;
Logger logger;
setUp(() async {
final Platform platform = FakePlatform(operatingSystem: 'macos');
logger = BufferLogger.test();
fileSystem = MemoryFileSystem.test();
artifacts = Artifacts.test();
processManager = FakeProcessManager.list(<FakeCommand>[]);
snapshotter = AOTSnapshotter(
fileSystem: fileSystem,
logger: logger,
xcode: Xcode(
fileSystem: fileSystem,
logger: logger,
platform: FakePlatform(operatingSystem: 'macos'),
logger: BufferLogger.test(),
xcode: Xcode.test(
processManager: processManager,
xcodeProjectInterpreter: XcodeProjectInterpreter(
platform: platform,
processManager: processManager,
logger: logger,
fileSystem: fileSystem,
terminal: Terminal.test(),
usage: Usage.test(),
),
),
artifacts: artifacts,
processManager: processManager,
......
......@@ -2,11 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:convert';
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/android/android_workflow.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/emulator.dart';
......@@ -45,14 +43,16 @@ const FakeCommand kListEmulatorsCommand = FakeCommand(
);
void main() {
MockProcessManager mockProcessManager;
FakeProcessManager fakeProcessManager;
MockAndroidSdk mockSdk;
MockXcode mockXcode;
FileSystem fileSystem;
Xcode xcode;
setUp(() {
mockProcessManager = MockProcessManager();
fileSystem = MemoryFileSystem.test();
fakeProcessManager = FakeProcessManager.list(<FakeCommand>[]);
mockSdk = MockAndroidSdk();
mockXcode = MockXcode();
xcode = Xcode.test(processManager: fakeProcessManager, fileSystem: fileSystem);
when(mockSdk.avdManagerPath).thenReturn('avdmanager');
when(mockSdk.getAvdManagerPath()).thenReturn('avdmanager');
......@@ -299,25 +299,35 @@ void main() {
});
group('ios_emulators', () {
bool didAttemptToRunSimulator = false;
setUp(() {
when(mockXcode.xcodeSelectPath).thenReturn('/fake/Xcode.app/Contents/Developer');
when(mockXcode.getSimulatorPath()).thenAnswer((_) => '/fake/simulator.app');
when(mockProcessManager.run(any)).thenAnswer((Invocation invocation) async {
final List<String> args = invocation.positionalArguments[0] as List<String>;
if (args.length >= 3 && args[0] == 'open' && args[1] == '-a' && args[2] == '/fake/simulator.app') {
didAttemptToRunSimulator = true;
}
return ProcessResult(101, 0, '', '');
});
});
testUsingContext('runs correct launch commands', () async {
fileSystem.directory('/fake/Xcode.app/Contents/Developer/Applications/Simulator.app').createSync(recursive: true);
fakeProcessManager.addCommands(
<FakeCommand>[
const FakeCommand(
command: <String>['/usr/bin/xcode-select', '--print-path'],
stdout: '/fake/Xcode.app/Contents/Developer',
),
const FakeCommand(command: <String>[
'open',
'-n',
'-a',
'/fake/Xcode.app/Contents/Developer/Applications/Simulator.app',
]),
const FakeCommand(command: <String>[
'open',
'-a',
'/fake/Xcode.app/Contents/Developer/Applications/Simulator.app',
])
],
);
const Emulator emulator = IOSEmulator('ios');
await emulator.launch();
expect(didAttemptToRunSimulator, equals(true));
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
}, overrides: <Type, Generator>{
ProcessManager: () => mockProcessManager,
Xcode: () => mockXcode,
ProcessManager: () => fakeProcessManager,
Xcode: () => xcode,
FileSystem: () => fileSystem,
});
});
}
......@@ -354,28 +364,3 @@ class FakeEmulator extends Emulator {
throw UnimplementedError('Not implemented in Mock');
}
}
class MockProcessManager extends Mock implements ProcessManager {
@override
ProcessResult runSync(
List<dynamic> command, {
String workingDirectory,
Map<String, String> environment,
bool includeParentEnvironment = true,
bool runInShell = false,
Encoding stdoutEncoding = systemEncoding,
Encoding stderrEncoding = systemEncoding,
}) {
final String program = command[0] as String;
final List<String> args = command.sublist(1) as List<String>;
switch (program) {
case '/usr/bin/xcode-select':
throw ProcessException(program, args);
break;
}
throw StateError('Unexpected process call: $command');
}
}
class MockXcode extends Mock implements Xcode {}
......@@ -80,7 +80,7 @@ void main() {
FileSystem fileSystem;
FakeProcessManager processManager;
BufferLogger logger;
MockXcode mockXcode;
Xcode xcode;
MockXcodeProjectInterpreter mockXcodeProjectInterpreter;
setUp(() {
......@@ -90,6 +90,8 @@ void main() {
mockXcodeProjectInterpreter = MockXcodeProjectInterpreter();
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(1000);
when(mockXcodeProjectInterpreter.xcrunCommand()).thenReturn(<String>['xcrun']);
when(mockXcodeProjectInterpreter.getInfo(any, projectFilename: anyNamed('projectFilename'))).thenAnswer(
(_) {
return Future<XcodeProjectInfo>.value(XcodeProjectInfo(
......@@ -100,9 +102,7 @@ void main() {
));
}
);
mockXcode = MockXcode();
when(mockXcode.isRequiredVersionSatisfactory).thenReturn(true);
when(mockXcode.xcrunCommand()).thenReturn(<String>['xcrun']);
xcode = Xcode.test(processManager: FakeProcessManager.any(), xcodeProjectInterpreter: mockXcodeProjectInterpreter);
fileSystem.file('foo/.packages')
..createSync(recursive: true)
..writeAsStringSync('\n');
......@@ -153,7 +153,7 @@ void main() {
Logger: () => logger,
Platform: () => macPlatform,
XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
Xcode: () => mockXcode,
Xcode: () => xcode,
});
testUsingContext('with flaky buildSettings call', () async {
......@@ -227,7 +227,7 @@ void main() {
Logger: () => logger,
Platform: () => macPlatform,
XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
Xcode: () => mockXcode,
Xcode: () => xcode,
});
testUsingContext('with concurrent build failures', () async {
......@@ -292,7 +292,7 @@ void main() {
Logger: () => logger,
Platform: () => macPlatform,
XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
Xcode: () => mockXcode,
Xcode: () => xcode,
}, skip: true); // TODO(jonahwilliams): clean up with https://github.com/flutter/flutter/issues/60675
});
}
......@@ -347,6 +347,5 @@ IOSDevice setUpIOSDevice({
);
}
class MockXcode extends Mock implements Xcode {}
class MockXcodeProjectInterpreter extends Mock implements XcodeProjectInterpreter {}
class MockVmService extends Mock implements VmService {}
......@@ -4,17 +4,18 @@
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/ios/ios_workflow.dart';
import 'package:flutter_tools/src/ios/xcodeproj.dart';
import 'package:flutter_tools/src/macos/xcode.dart';
import 'package:mockito/mockito.dart';
import '../../src/common.dart';
import '../../src/context.dart';
import '../../src/testbed.dart';
void main() {
testWithoutContext('iOS workflow is disabled if feature is disabled', () {
final IOSWorkflow iosWorkflow = IOSWorkflow(
platform: FakePlatform(operatingSystem: 'macOS'),
xcode: MockXcode(),
xcode: Xcode.test(processManager: FakeProcessManager.any()),
featureFlags: TestFeatureFlags(isIOSEnabled: false),
);
......@@ -24,7 +25,7 @@ void main() {
testWithoutContext('iOS workflow is disabled on Linux', () {
final IOSWorkflow iosWorkflow = IOSWorkflow(
platform: FakePlatform(operatingSystem: 'linux'),
xcode: MockXcode(),
xcode: Xcode.test(processManager: FakeProcessManager.any()),
featureFlags: TestFeatureFlags(isIOSEnabled: true),
);
......@@ -34,7 +35,7 @@ void main() {
testWithoutContext('iOS workflow is disabled on windows', () {
final IOSWorkflow iosWorkflow = IOSWorkflow(
platform: FakePlatform(operatingSystem: 'windows'),
xcode: MockXcode(),
xcode: Xcode.test(processManager: FakeProcessManager.any()),
featureFlags: TestFeatureFlags(isIOSEnabled: true),
);
......@@ -44,7 +45,7 @@ void main() {
testWithoutContext('iOS workflow is enabled on macOS', () {
final IOSWorkflow iosWorkflow = IOSWorkflow(
platform: FakePlatform(operatingSystem: 'macos'),
xcode: MockXcode(),
xcode: Xcode.test(processManager: FakeProcessManager.any()),
featureFlags: TestFeatureFlags(isIOSEnabled: true),
);
......@@ -53,18 +54,26 @@ void main() {
});
testWithoutContext('iOS workflow can launch and list devices when Xcode is set up', () {
final Xcode xcode = MockXcode();
final Xcode xcode = Xcode.test(
processManager: FakeProcessManager.any(),
xcodeProjectInterpreter: XcodeProjectInterpreter.test(
processManager: FakeProcessManager.any(),
majorVersion: 1000,
minorVersion: 0,
patchVersion: 0,
),
);
final IOSWorkflow iosWorkflow = IOSWorkflow(
platform: FakePlatform(operatingSystem: 'macos'),
xcode: xcode,
featureFlags: TestFeatureFlags(isIOSEnabled: true),
);
when(xcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
when(xcode.isSimctlInstalled).thenReturn(true);
// Make sure we're testing the right Xcode state.
expect(xcode.isInstalledAndMeetsVersionCheck, true);
expect(xcode.isSimctlInstalled, true);
expect(iosWorkflow.canLaunchDevices, true);
expect(iosWorkflow.canListDevices, true);
});
}
class MockXcode extends Mock implements Xcode {}
......@@ -13,7 +13,6 @@ import 'package:flutter_tools/src/base/process.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/ios/devices.dart';
import 'package:flutter_tools/src/ios/mac.dart';
import 'package:flutter_tools/src/ios/xcodeproj.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:mockito/mockito.dart';
......@@ -29,7 +28,6 @@ final Map<Type, Generator> noColorTerminalOverride = <Type, Generator>{
};
class MockProcessManager extends Mock implements ProcessManager {}
class MockXcodeProjectInterpreter extends Mock implements XcodeProjectInterpreter {}
class MockIosProject extends Mock implements IosProject {}
void main() {
......
......@@ -306,12 +306,12 @@ void main() {
});
group('language', () {
MockXcodeProjectInterpreter mockXcodeProjectInterpreter;
XcodeProjectInterpreter xcodeProjectInterpreter;
MemoryFileSystem fs;
FlutterProjectFactory flutterProjectFactory;
setUp(() {
fs = MemoryFileSystem.test();
mockXcodeProjectInterpreter = MockXcodeProjectInterpreter();
xcodeProjectInterpreter = XcodeProjectInterpreter.test(processManager: FakeProcessManager.any());
flutterProjectFactory = FlutterProjectFactory(
logger: logger,
fileSystem: fs,
......@@ -337,7 +337,7 @@ apply plugin: 'kotlin-android'
}, overrides: <Type, Generator>{
FileSystem: () => fs,
ProcessManager: () => FakeProcessManager.any(),
XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
XcodeProjectInterpreter: () => xcodeProjectInterpreter,
FlutterProjectFactory: () => flutterProjectFactory,
});
});
......
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