Replace MockXcode with Xcode.test in more unit tests (#74827)
This commit is contained in:
parent
91437a0641
commit
fe921211df
@ -19,20 +19,24 @@ import '../../src/context.dart';
|
|||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('clean command', () {
|
group('clean command', () {
|
||||||
MockXcode mockXcode;
|
Xcode xcode;
|
||||||
|
MockXcodeProjectInterpreter mockXcodeProjectInterpreter;
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
mockXcode = MockXcode();
|
mockXcodeProjectInterpreter = MockXcodeProjectInterpreter();
|
||||||
|
xcode = Xcode.test(
|
||||||
|
processManager: FakeProcessManager.any(),
|
||||||
|
xcodeProjectInterpreter: mockXcodeProjectInterpreter,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('general', () {
|
group('general', () {
|
||||||
MemoryFileSystem fs;
|
MemoryFileSystem fs;
|
||||||
MockXcodeProjectInterpreter mockXcodeProjectInterpreter;
|
|
||||||
Directory buildDirectory;
|
Directory buildDirectory;
|
||||||
FlutterProject projectUnderTest;
|
FlutterProject projectUnderTest;
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
fs = MemoryFileSystem.test();
|
fs = MemoryFileSystem.test();
|
||||||
mockXcodeProjectInterpreter = MockXcodeProjectInterpreter();
|
|
||||||
|
|
||||||
final Directory currentDirectory = fs.currentDirectory;
|
final Directory currentDirectory = fs.currentDirectory;
|
||||||
buildDirectory = currentDirectory.childDirectory('build');
|
buildDirectory = currentDirectory.childDirectory('build');
|
||||||
@ -61,7 +65,9 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('$CleanCommand removes build and .dart_tool and ephemeral directories, cleans Xcode', () async {
|
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();
|
await CleanCommand().runCommand();
|
||||||
|
|
||||||
expect(buildDirectory.existsSync(), isFalse);
|
expect(buildDirectory.existsSync(), isFalse);
|
||||||
@ -87,31 +93,33 @@ void main() {
|
|||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
FileSystem: () => fs,
|
FileSystem: () => fs,
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
Xcode: () => mockXcode,
|
Xcode: () => xcode,
|
||||||
XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
|
XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('$CleanCommand cleans Xcode verbosely', () async {
|
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();
|
await CleanCommand(verbose: true).runCommand();
|
||||||
verify(mockXcodeProjectInterpreter.cleanWorkspace(any, 'Runner', verbose: true)).called(2);
|
verify(mockXcodeProjectInterpreter.cleanWorkspace(any, 'Runner', verbose: true)).called(2);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
FileSystem: () => fs,
|
FileSystem: () => fs,
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
Xcode: () => mockXcode,
|
Xcode: () => xcode,
|
||||||
XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
|
XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Windows', () {
|
group('Windows', () {
|
||||||
MockPlatform windowsPlatform;
|
FakePlatform windowsPlatform;
|
||||||
setUp(() {
|
setUp(() {
|
||||||
windowsPlatform = MockPlatform();
|
windowsPlatform = FakePlatform(operatingSystem: 'windows');
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('$CleanCommand prints a helpful error message on Windows', () async {
|
testUsingContext('$CleanCommand prints a helpful error message on Windows', () async {
|
||||||
when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(false);
|
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(false);
|
||||||
when(windowsPlatform.isWindows).thenReturn(true);
|
|
||||||
|
|
||||||
final MockFile mockFile = MockFile();
|
final MockFile mockFile = MockFile();
|
||||||
when(mockFile.existsSync()).thenReturn(true);
|
when(mockFile.existsSync()).thenReturn(true);
|
||||||
@ -123,11 +131,11 @@ void main() {
|
|||||||
verify(mockFile.deleteSync(recursive: true)).called(1);
|
verify(mockFile.deleteSync(recursive: true)).called(1);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
Platform: () => windowsPlatform,
|
Platform: () => windowsPlatform,
|
||||||
Xcode: () => mockXcode,
|
Xcode: () => xcode,
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('$CleanCommand handles missing permissions;', () async {
|
testUsingContext('$CleanCommand handles missing permissions;', () async {
|
||||||
when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(false);
|
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(false);
|
||||||
|
|
||||||
final MockFile mockFile = MockFile();
|
final MockFile mockFile = MockFile();
|
||||||
when(mockFile.existsSync()).thenThrow(const FileSystemException('OS error: Access Denied'));
|
when(mockFile.existsSync()).thenThrow(const FileSystemException('OS error: Access Denied'));
|
||||||
@ -139,15 +147,13 @@ void main() {
|
|||||||
verifyNever(mockFile.deleteSync(recursive: true));
|
verifyNever(mockFile.deleteSync(recursive: true));
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
Platform: () => windowsPlatform,
|
Platform: () => windowsPlatform,
|
||||||
Xcode: () => mockXcode,
|
Xcode: () => xcode,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class MockFile extends Mock implements File {}
|
class MockFile extends Mock implements File {}
|
||||||
class MockPlatform extends Mock implements Platform {}
|
|
||||||
class MockXcode extends Mock implements Xcode {}
|
|
||||||
|
|
||||||
class MockXcodeProjectInterpreter extends Mock implements XcodeProjectInterpreter {
|
class MockXcodeProjectInterpreter extends Mock implements XcodeProjectInterpreter {
|
||||||
@override
|
@override
|
||||||
|
@ -6,12 +6,8 @@ import 'package:file/memory.dart';
|
|||||||
import 'package:flutter_tools/src/artifacts.dart';
|
import 'package:flutter_tools/src/artifacts.dart';
|
||||||
import 'package:flutter_tools/src/base/build.dart';
|
import 'package:flutter_tools/src/base/build.dart';
|
||||||
import 'package:flutter_tools/src/base/logger.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/build_info.dart';
|
||||||
import 'package:flutter_tools/src/ios/xcodeproj.dart';
|
|
||||||
import 'package:flutter_tools/src/macos/xcode.dart';
|
import 'package:flutter_tools/src/macos/xcode.dart';
|
||||||
import 'package:flutter_tools/src/reporting/reporting.dart';
|
|
||||||
|
|
||||||
import '../../src/common.dart';
|
import '../../src/common.dart';
|
||||||
import '../../src/context.dart';
|
import '../../src/context.dart';
|
||||||
@ -185,30 +181,16 @@ void main() {
|
|||||||
AOTSnapshotter snapshotter;
|
AOTSnapshotter snapshotter;
|
||||||
Artifacts artifacts;
|
Artifacts artifacts;
|
||||||
FakeProcessManager processManager;
|
FakeProcessManager processManager;
|
||||||
Logger logger;
|
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() async {
|
||||||
final Platform platform = FakePlatform(operatingSystem: 'macos');
|
|
||||||
logger = BufferLogger.test();
|
|
||||||
fileSystem = MemoryFileSystem.test();
|
fileSystem = MemoryFileSystem.test();
|
||||||
artifacts = Artifacts.test();
|
artifacts = Artifacts.test();
|
||||||
processManager = FakeProcessManager.list(<FakeCommand>[]);
|
processManager = FakeProcessManager.list(<FakeCommand>[]);
|
||||||
snapshotter = AOTSnapshotter(
|
snapshotter = AOTSnapshotter(
|
||||||
fileSystem: fileSystem,
|
fileSystem: fileSystem,
|
||||||
logger: logger,
|
logger: BufferLogger.test(),
|
||||||
xcode: Xcode(
|
xcode: Xcode.test(
|
||||||
fileSystem: fileSystem,
|
|
||||||
logger: logger,
|
|
||||||
platform: FakePlatform(operatingSystem: 'macos'),
|
|
||||||
processManager: processManager,
|
processManager: processManager,
|
||||||
xcodeProjectInterpreter: XcodeProjectInterpreter(
|
|
||||||
platform: platform,
|
|
||||||
processManager: processManager,
|
|
||||||
logger: logger,
|
|
||||||
fileSystem: fileSystem,
|
|
||||||
terminal: Terminal.test(),
|
|
||||||
usage: Usage.test(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
artifacts: artifacts,
|
artifacts: artifacts,
|
||||||
processManager: processManager,
|
processManager: processManager,
|
||||||
|
@ -2,11 +2,9 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'dart:convert';
|
import 'package:file/file.dart';
|
||||||
|
|
||||||
import 'package:file/memory.dart';
|
import 'package:file/memory.dart';
|
||||||
import 'package:flutter_tools/src/android/android_workflow.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/base/logger.dart';
|
||||||
import 'package:flutter_tools/src/device.dart';
|
import 'package:flutter_tools/src/device.dart';
|
||||||
import 'package:flutter_tools/src/emulator.dart';
|
import 'package:flutter_tools/src/emulator.dart';
|
||||||
@ -45,14 +43,16 @@ const FakeCommand kListEmulatorsCommand = FakeCommand(
|
|||||||
);
|
);
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
MockProcessManager mockProcessManager;
|
FakeProcessManager fakeProcessManager;
|
||||||
MockAndroidSdk mockSdk;
|
MockAndroidSdk mockSdk;
|
||||||
MockXcode mockXcode;
|
FileSystem fileSystem;
|
||||||
|
Xcode xcode;
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
mockProcessManager = MockProcessManager();
|
fileSystem = MemoryFileSystem.test();
|
||||||
|
fakeProcessManager = FakeProcessManager.list(<FakeCommand>[]);
|
||||||
mockSdk = MockAndroidSdk();
|
mockSdk = MockAndroidSdk();
|
||||||
mockXcode = MockXcode();
|
xcode = Xcode.test(processManager: fakeProcessManager, fileSystem: fileSystem);
|
||||||
|
|
||||||
when(mockSdk.avdManagerPath).thenReturn('avdmanager');
|
when(mockSdk.avdManagerPath).thenReturn('avdmanager');
|
||||||
when(mockSdk.getAvdManagerPath()).thenReturn('avdmanager');
|
when(mockSdk.getAvdManagerPath()).thenReturn('avdmanager');
|
||||||
@ -299,25 +299,35 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
group('ios_emulators', () {
|
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 {
|
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');
|
const Emulator emulator = IOSEmulator('ios');
|
||||||
await emulator.launch();
|
await emulator.launch();
|
||||||
expect(didAttemptToRunSimulator, equals(true));
|
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
ProcessManager: () => mockProcessManager,
|
ProcessManager: () => fakeProcessManager,
|
||||||
Xcode: () => mockXcode,
|
Xcode: () => xcode,
|
||||||
|
FileSystem: () => fileSystem,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -354,28 +364,3 @@ class FakeEmulator extends Emulator {
|
|||||||
throw UnimplementedError('Not implemented in Mock');
|
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;
|
FileSystem fileSystem;
|
||||||
FakeProcessManager processManager;
|
FakeProcessManager processManager;
|
||||||
BufferLogger logger;
|
BufferLogger logger;
|
||||||
MockXcode mockXcode;
|
Xcode xcode;
|
||||||
MockXcodeProjectInterpreter mockXcodeProjectInterpreter;
|
MockXcodeProjectInterpreter mockXcodeProjectInterpreter;
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
@ -90,6 +90,8 @@ void main() {
|
|||||||
|
|
||||||
mockXcodeProjectInterpreter = MockXcodeProjectInterpreter();
|
mockXcodeProjectInterpreter = MockXcodeProjectInterpreter();
|
||||||
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
|
when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
|
||||||
|
when(mockXcodeProjectInterpreter.majorVersion).thenReturn(1000);
|
||||||
|
when(mockXcodeProjectInterpreter.xcrunCommand()).thenReturn(<String>['xcrun']);
|
||||||
when(mockXcodeProjectInterpreter.getInfo(any, projectFilename: anyNamed('projectFilename'))).thenAnswer(
|
when(mockXcodeProjectInterpreter.getInfo(any, projectFilename: anyNamed('projectFilename'))).thenAnswer(
|
||||||
(_) {
|
(_) {
|
||||||
return Future<XcodeProjectInfo>.value(XcodeProjectInfo(
|
return Future<XcodeProjectInfo>.value(XcodeProjectInfo(
|
||||||
@ -100,9 +102,7 @@ void main() {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
mockXcode = MockXcode();
|
xcode = Xcode.test(processManager: FakeProcessManager.any(), xcodeProjectInterpreter: mockXcodeProjectInterpreter);
|
||||||
when(mockXcode.isRequiredVersionSatisfactory).thenReturn(true);
|
|
||||||
when(mockXcode.xcrunCommand()).thenReturn(<String>['xcrun']);
|
|
||||||
fileSystem.file('foo/.packages')
|
fileSystem.file('foo/.packages')
|
||||||
..createSync(recursive: true)
|
..createSync(recursive: true)
|
||||||
..writeAsStringSync('\n');
|
..writeAsStringSync('\n');
|
||||||
@ -153,7 +153,7 @@ void main() {
|
|||||||
Logger: () => logger,
|
Logger: () => logger,
|
||||||
Platform: () => macPlatform,
|
Platform: () => macPlatform,
|
||||||
XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
|
XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
|
||||||
Xcode: () => mockXcode,
|
Xcode: () => xcode,
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('with flaky buildSettings call', () async {
|
testUsingContext('with flaky buildSettings call', () async {
|
||||||
@ -227,7 +227,7 @@ void main() {
|
|||||||
Logger: () => logger,
|
Logger: () => logger,
|
||||||
Platform: () => macPlatform,
|
Platform: () => macPlatform,
|
||||||
XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
|
XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
|
||||||
Xcode: () => mockXcode,
|
Xcode: () => xcode,
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('with concurrent build failures', () async {
|
testUsingContext('with concurrent build failures', () async {
|
||||||
@ -292,7 +292,7 @@ void main() {
|
|||||||
Logger: () => logger,
|
Logger: () => logger,
|
||||||
Platform: () => macPlatform,
|
Platform: () => macPlatform,
|
||||||
XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
|
XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
|
||||||
Xcode: () => mockXcode,
|
Xcode: () => xcode,
|
||||||
}, skip: true); // TODO(jonahwilliams): clean up with https://github.com/flutter/flutter/issues/60675
|
}, 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 MockXcodeProjectInterpreter extends Mock implements XcodeProjectInterpreter {}
|
||||||
class MockVmService extends Mock implements VmService {}
|
class MockVmService extends Mock implements VmService {}
|
||||||
|
@ -4,17 +4,18 @@
|
|||||||
|
|
||||||
import 'package:flutter_tools/src/base/platform.dart';
|
import 'package:flutter_tools/src/base/platform.dart';
|
||||||
import 'package:flutter_tools/src/ios/ios_workflow.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:flutter_tools/src/macos/xcode.dart';
|
||||||
import 'package:mockito/mockito.dart';
|
|
||||||
|
|
||||||
import '../../src/common.dart';
|
import '../../src/common.dart';
|
||||||
|
import '../../src/context.dart';
|
||||||
import '../../src/testbed.dart';
|
import '../../src/testbed.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
testWithoutContext('iOS workflow is disabled if feature is disabled', () {
|
testWithoutContext('iOS workflow is disabled if feature is disabled', () {
|
||||||
final IOSWorkflow iosWorkflow = IOSWorkflow(
|
final IOSWorkflow iosWorkflow = IOSWorkflow(
|
||||||
platform: FakePlatform(operatingSystem: 'macOS'),
|
platform: FakePlatform(operatingSystem: 'macOS'),
|
||||||
xcode: MockXcode(),
|
xcode: Xcode.test(processManager: FakeProcessManager.any()),
|
||||||
featureFlags: TestFeatureFlags(isIOSEnabled: false),
|
featureFlags: TestFeatureFlags(isIOSEnabled: false),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -24,7 +25,7 @@ void main() {
|
|||||||
testWithoutContext('iOS workflow is disabled on Linux', () {
|
testWithoutContext('iOS workflow is disabled on Linux', () {
|
||||||
final IOSWorkflow iosWorkflow = IOSWorkflow(
|
final IOSWorkflow iosWorkflow = IOSWorkflow(
|
||||||
platform: FakePlatform(operatingSystem: 'linux'),
|
platform: FakePlatform(operatingSystem: 'linux'),
|
||||||
xcode: MockXcode(),
|
xcode: Xcode.test(processManager: FakeProcessManager.any()),
|
||||||
featureFlags: TestFeatureFlags(isIOSEnabled: true),
|
featureFlags: TestFeatureFlags(isIOSEnabled: true),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -34,7 +35,7 @@ void main() {
|
|||||||
testWithoutContext('iOS workflow is disabled on windows', () {
|
testWithoutContext('iOS workflow is disabled on windows', () {
|
||||||
final IOSWorkflow iosWorkflow = IOSWorkflow(
|
final IOSWorkflow iosWorkflow = IOSWorkflow(
|
||||||
platform: FakePlatform(operatingSystem: 'windows'),
|
platform: FakePlatform(operatingSystem: 'windows'),
|
||||||
xcode: MockXcode(),
|
xcode: Xcode.test(processManager: FakeProcessManager.any()),
|
||||||
featureFlags: TestFeatureFlags(isIOSEnabled: true),
|
featureFlags: TestFeatureFlags(isIOSEnabled: true),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -44,7 +45,7 @@ void main() {
|
|||||||
testWithoutContext('iOS workflow is enabled on macOS', () {
|
testWithoutContext('iOS workflow is enabled on macOS', () {
|
||||||
final IOSWorkflow iosWorkflow = IOSWorkflow(
|
final IOSWorkflow iosWorkflow = IOSWorkflow(
|
||||||
platform: FakePlatform(operatingSystem: 'macos'),
|
platform: FakePlatform(operatingSystem: 'macos'),
|
||||||
xcode: MockXcode(),
|
xcode: Xcode.test(processManager: FakeProcessManager.any()),
|
||||||
featureFlags: TestFeatureFlags(isIOSEnabled: true),
|
featureFlags: TestFeatureFlags(isIOSEnabled: true),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -53,18 +54,26 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('iOS workflow can launch and list devices when Xcode is set up', () {
|
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(
|
final IOSWorkflow iosWorkflow = IOSWorkflow(
|
||||||
platform: FakePlatform(operatingSystem: 'macos'),
|
platform: FakePlatform(operatingSystem: 'macos'),
|
||||||
xcode: xcode,
|
xcode: xcode,
|
||||||
featureFlags: TestFeatureFlags(isIOSEnabled: true),
|
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.canLaunchDevices, true);
|
||||||
expect(iosWorkflow.canListDevices, 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/cache.dart';
|
||||||
import 'package:flutter_tools/src/ios/devices.dart';
|
import 'package:flutter_tools/src/ios/devices.dart';
|
||||||
import 'package:flutter_tools/src/ios/mac.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/project.dart';
|
||||||
import 'package:flutter_tools/src/reporting/reporting.dart';
|
import 'package:flutter_tools/src/reporting/reporting.dart';
|
||||||
import 'package:mockito/mockito.dart';
|
import 'package:mockito/mockito.dart';
|
||||||
@ -29,7 +28,6 @@ final Map<Type, Generator> noColorTerminalOverride = <Type, Generator>{
|
|||||||
};
|
};
|
||||||
|
|
||||||
class MockProcessManager extends Mock implements ProcessManager {}
|
class MockProcessManager extends Mock implements ProcessManager {}
|
||||||
class MockXcodeProjectInterpreter extends Mock implements XcodeProjectInterpreter {}
|
|
||||||
class MockIosProject extends Mock implements IosProject {}
|
class MockIosProject extends Mock implements IosProject {}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'dart:io' show ProcessResult, Process;
|
|
||||||
|
|
||||||
import 'package:file/file.dart';
|
import 'package:file/file.dart';
|
||||||
import 'package:file/memory.dart';
|
import 'package:file/memory.dart';
|
||||||
import 'package:flutter_tools/src/application_package.dart';
|
import 'package:flutter_tools/src/application_package.dart';
|
||||||
@ -16,7 +14,6 @@ import 'package:flutter_tools/src/build_system/build_system.dart';
|
|||||||
import 'package:flutter_tools/src/devfs.dart';
|
import 'package:flutter_tools/src/devfs.dart';
|
||||||
import 'package:flutter_tools/src/device.dart';
|
import 'package:flutter_tools/src/device.dart';
|
||||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||||
import 'package:flutter_tools/src/ios/mac.dart';
|
|
||||||
import 'package:flutter_tools/src/ios/plist_parser.dart';
|
import 'package:flutter_tools/src/ios/plist_parser.dart';
|
||||||
import 'package:flutter_tools/src/ios/simulators.dart';
|
import 'package:flutter_tools/src/ios/simulators.dart';
|
||||||
import 'package:flutter_tools/src/macos/xcode.dart';
|
import 'package:flutter_tools/src/macos/xcode.dart';
|
||||||
@ -28,12 +25,6 @@ import '../../src/common.dart';
|
|||||||
import '../../src/context.dart';
|
import '../../src/context.dart';
|
||||||
import '../../src/mocks.dart';
|
import '../../src/mocks.dart';
|
||||||
|
|
||||||
class MockIMobileDevice extends Mock implements IMobileDevice {}
|
|
||||||
class MockLogger extends Mock implements Logger {}
|
|
||||||
class MockProcess extends Mock implements Process {}
|
|
||||||
class MockProcessManager extends Mock implements ProcessManager {}
|
|
||||||
class MockXcode extends Mock implements Xcode {}
|
|
||||||
class MockSimControl extends Mock implements SimControl {}
|
|
||||||
class MockPlistUtils extends Mock implements PlistParser {}
|
class MockPlistUtils extends Mock implements PlistParser {}
|
||||||
|
|
||||||
final Platform macosPlatform = FakePlatform(
|
final Platform macosPlatform = FakePlatform(
|
||||||
@ -59,11 +50,11 @@ void main() {
|
|||||||
|
|
||||||
group('_IOSSimulatorDevicePortForwarder', () {
|
group('_IOSSimulatorDevicePortForwarder', () {
|
||||||
MockSimControl mockSimControl;
|
MockSimControl mockSimControl;
|
||||||
MockXcode mockXcode;
|
Xcode xcode;
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
mockSimControl = MockSimControl();
|
mockSimControl = MockSimControl();
|
||||||
mockXcode = MockXcode();
|
xcode = Xcode.test(processManager: FakeProcessManager.any());
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('dispose() does not throw an exception', () async {
|
testUsingContext('dispose() does not throw an exception', () async {
|
||||||
@ -85,7 +76,7 @@ void main() {
|
|||||||
Platform: () => osx,
|
Platform: () => osx,
|
||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
Xcode: () => mockXcode,
|
Xcode: () => xcode,
|
||||||
}, testOn: 'posix');
|
}, testOn: 'posix');
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -351,44 +342,12 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
group('Simulator screenshot', () {
|
group('Simulator screenshot', () {
|
||||||
MockXcode mockXcode;
|
testWithoutContext('supports screenshots', () async {
|
||||||
MockLogger mockLogger;
|
final Xcode xcode = Xcode.test(processManager: FakeProcessManager.any());
|
||||||
MockProcessManager mockProcessManager;
|
final Logger logger = BufferLogger.test();
|
||||||
IOSSimulator deviceUnderTest;
|
final FakeProcessManager fakeProcessManager = FakeProcessManager.list(<FakeCommand>[
|
||||||
|
const FakeCommand(
|
||||||
setUp(() {
|
command: <String>[
|
||||||
mockXcode = MockXcode();
|
|
||||||
mockLogger = MockLogger();
|
|
||||||
mockProcessManager = MockProcessManager();
|
|
||||||
// Let everything else return exit code 0 so process.dart doesn't crash.
|
|
||||||
when(
|
|
||||||
mockProcessManager.run(any, environment: null, workingDirectory: null)
|
|
||||||
).thenAnswer((Invocation invocation) =>
|
|
||||||
Future<ProcessResult>.value(ProcessResult(2, 0, '', ''))
|
|
||||||
);
|
|
||||||
// Test a real one. Screenshot doesn't require instance states.
|
|
||||||
final SimControl simControl = SimControl(
|
|
||||||
processManager: mockProcessManager,
|
|
||||||
logger: mockLogger,
|
|
||||||
xcode: mockXcode,
|
|
||||||
);
|
|
||||||
// Doesn't matter what the device is.
|
|
||||||
deviceUnderTest = IOSSimulator(
|
|
||||||
'x',
|
|
||||||
name: 'iPhone SE',
|
|
||||||
simControl: simControl,
|
|
||||||
);
|
|
||||||
when(mockXcode.xcrunCommand()).thenReturn(<String>['xcrun']);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
testWithoutContext(
|
|
||||||
'supports screenshots',
|
|
||||||
() async {
|
|
||||||
final File screenshot = MemoryFileSystem.test().file('screenshot.png');
|
|
||||||
await deviceUnderTest.takeScreenshot(screenshot);
|
|
||||||
verify(mockProcessManager.run(
|
|
||||||
<String>[
|
|
||||||
'xcrun',
|
'xcrun',
|
||||||
'simctl',
|
'simctl',
|
||||||
'io',
|
'io',
|
||||||
@ -396,25 +355,35 @@ void main() {
|
|||||||
'screenshot',
|
'screenshot',
|
||||||
'screenshot.png',
|
'screenshot.png',
|
||||||
],
|
],
|
||||||
environment: null,
|
),
|
||||||
workingDirectory: null,
|
]);
|
||||||
));
|
|
||||||
},
|
// Test a real one. Screenshot doesn't require instance states.
|
||||||
);
|
final SimControl simControl = SimControl(
|
||||||
|
processManager: fakeProcessManager,
|
||||||
|
logger: logger,
|
||||||
|
xcode: xcode,
|
||||||
|
);
|
||||||
|
// Doesn't matter what the device is.
|
||||||
|
final IOSSimulator deviceUnderTest = IOSSimulator(
|
||||||
|
'x',
|
||||||
|
name: 'iPhone SE',
|
||||||
|
simControl: simControl,
|
||||||
|
);
|
||||||
|
|
||||||
|
final File screenshot = MemoryFileSystem.test().file('screenshot.png');
|
||||||
|
await deviceUnderTest.takeScreenshot(screenshot);
|
||||||
|
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group('device log tool', () {
|
group('device log tool', () {
|
||||||
MockProcessManager mockProcessManager;
|
FakeProcessManager fakeProcessManager;
|
||||||
MockXcode mockXcode;
|
|
||||||
MockSimControl mockSimControl;
|
MockSimControl mockSimControl;
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
mockProcessManager = MockProcessManager();
|
fakeProcessManager = FakeProcessManager.list(<FakeCommand>[]);
|
||||||
when(mockProcessManager.start(any, environment: null, workingDirectory: null))
|
|
||||||
.thenAnswer((Invocation invocation) => Future<Process>.value(MockProcess()));
|
|
||||||
mockSimControl = MockSimControl();
|
mockSimControl = MockSimControl();
|
||||||
mockXcode = MockXcode();
|
|
||||||
when(mockXcode.xcrunCommand()).thenReturn(<String>['xcrun']);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('syslog uses tail', () async {
|
testUsingContext('syslog uses tail', () async {
|
||||||
@ -424,14 +393,18 @@ void main() {
|
|||||||
simulatorCategory: 'iOS 9.3',
|
simulatorCategory: 'iOS 9.3',
|
||||||
simControl: mockSimControl,
|
simControl: mockSimControl,
|
||||||
);
|
);
|
||||||
|
fakeProcessManager.addCommand(const FakeCommand(command: <String>[
|
||||||
|
'tail',
|
||||||
|
'-n',
|
||||||
|
'0',
|
||||||
|
'-F',
|
||||||
|
'/Library/Logs/CoreSimulator/x/system.log',
|
||||||
|
]));
|
||||||
await launchDeviceSystemLogTool(device);
|
await launchDeviceSystemLogTool(device);
|
||||||
expect(
|
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
|
||||||
verify(mockProcessManager.start(captureAny, environment: null, workingDirectory: null)).captured.single,
|
|
||||||
contains('tail'),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
overrides: <Type, Generator>{
|
overrides: <Type, Generator>{
|
||||||
ProcessManager: () => mockProcessManager,
|
ProcessManager: () => fakeProcessManager,
|
||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
Platform: () => macosPlatform,
|
Platform: () => macosPlatform,
|
||||||
FileSystemUtils: () => FileSystemUtils(
|
FileSystemUtils: () => FileSystemUtils(
|
||||||
@ -447,17 +420,13 @@ void main() {
|
|||||||
simulatorCategory: 'iOS 11.0',
|
simulatorCategory: 'iOS 11.0',
|
||||||
simControl: mockSimControl,
|
simControl: mockSimControl,
|
||||||
);
|
);
|
||||||
await launchDeviceUnifiedLogging(device, 'My Super Awesome App');
|
|
||||||
|
|
||||||
const String expectedPredicate = 'eventType = logEvent AND '
|
const String expectedPredicate = 'eventType = logEvent AND '
|
||||||
'processImagePath ENDSWITH "My Super Awesome App" AND '
|
'processImagePath ENDSWITH "My Super Awesome App" AND '
|
||||||
'(senderImagePath ENDSWITH "/Flutter" OR senderImagePath ENDSWITH "/libswiftCore.dylib" OR processImageUUID == senderImageUUID) AND '
|
'(senderImagePath ENDSWITH "/Flutter" OR senderImagePath ENDSWITH "/libswiftCore.dylib" OR processImageUUID == senderImageUUID) AND '
|
||||||
'NOT(eventMessage CONTAINS ": could not find icon for representation -> com.apple.") AND '
|
'NOT(eventMessage CONTAINS ": could not find icon for representation -> com.apple.") AND '
|
||||||
'NOT(eventMessage BEGINSWITH "assertion failed: ") AND '
|
'NOT(eventMessage BEGINSWITH "assertion failed: ") AND '
|
||||||
'NOT(eventMessage CONTAINS " libxpc.dylib ")';
|
'NOT(eventMessage CONTAINS " libxpc.dylib ")';
|
||||||
|
fakeProcessManager.addCommand(const FakeCommand(command: <String>[
|
||||||
final List<String> command = verify(mockProcessManager.start(captureAny, environment: null, workingDirectory: null)).captured.single as List<String>;
|
|
||||||
expect(command, <String>[
|
|
||||||
'xcrun',
|
'xcrun',
|
||||||
'simctl',
|
'simctl',
|
||||||
'spawn',
|
'spawn',
|
||||||
@ -467,13 +436,15 @@ void main() {
|
|||||||
'--style',
|
'--style',
|
||||||
'json',
|
'json',
|
||||||
'--predicate',
|
'--predicate',
|
||||||
expectedPredicate
|
expectedPredicate,
|
||||||
]);
|
]));
|
||||||
|
|
||||||
|
await launchDeviceUnifiedLogging(device, 'My Super Awesome App');
|
||||||
|
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
|
||||||
},
|
},
|
||||||
overrides: <Type, Generator>{
|
overrides: <Type, Generator>{
|
||||||
ProcessManager: () => mockProcessManager,
|
ProcessManager: () => fakeProcessManager,
|
||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
Xcode: () => mockXcode,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('unified logging without app name', () async {
|
testUsingContext('unified logging without app name', () async {
|
||||||
@ -483,16 +454,12 @@ void main() {
|
|||||||
simulatorCategory: 'iOS 11.0',
|
simulatorCategory: 'iOS 11.0',
|
||||||
simControl: mockSimControl,
|
simControl: mockSimControl,
|
||||||
);
|
);
|
||||||
await launchDeviceUnifiedLogging(device, null);
|
|
||||||
|
|
||||||
const String expectedPredicate = 'eventType = logEvent AND '
|
const String expectedPredicate = 'eventType = logEvent AND '
|
||||||
'(senderImagePath ENDSWITH "/Flutter" OR senderImagePath ENDSWITH "/libswiftCore.dylib" OR processImageUUID == senderImageUUID) AND '
|
'(senderImagePath ENDSWITH "/Flutter" OR senderImagePath ENDSWITH "/libswiftCore.dylib" OR processImageUUID == senderImageUUID) AND '
|
||||||
'NOT(eventMessage CONTAINS ": could not find icon for representation -> com.apple.") AND '
|
'NOT(eventMessage CONTAINS ": could not find icon for representation -> com.apple.") AND '
|
||||||
'NOT(eventMessage BEGINSWITH "assertion failed: ") AND '
|
'NOT(eventMessage BEGINSWITH "assertion failed: ") AND '
|
||||||
'NOT(eventMessage CONTAINS " libxpc.dylib ")';
|
'NOT(eventMessage CONTAINS " libxpc.dylib ")';
|
||||||
|
fakeProcessManager.addCommand(const FakeCommand(command: <String>[
|
||||||
final List<String> command = verify(mockProcessManager.start(captureAny, environment: null, workingDirectory: null)).captured.single as List<String>;
|
|
||||||
expect(command, <String>[
|
|
||||||
'xcrun',
|
'xcrun',
|
||||||
'simctl',
|
'simctl',
|
||||||
'spawn',
|
'spawn',
|
||||||
@ -502,11 +469,14 @@ void main() {
|
|||||||
'--style',
|
'--style',
|
||||||
'json',
|
'json',
|
||||||
'--predicate',
|
'--predicate',
|
||||||
expectedPredicate
|
expectedPredicate,
|
||||||
]);
|
]));
|
||||||
|
|
||||||
|
await launchDeviceUnifiedLogging(device, null);
|
||||||
|
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
|
||||||
},
|
},
|
||||||
overrides: <Type, Generator>{
|
overrides: <Type, Generator>{
|
||||||
ProcessManager: () => mockProcessManager,
|
ProcessManager: () => fakeProcessManager,
|
||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -515,14 +485,13 @@ void main() {
|
|||||||
FakeProcessManager fakeProcessManager;
|
FakeProcessManager fakeProcessManager;
|
||||||
MockIosProject mockIosProject;
|
MockIosProject mockIosProject;
|
||||||
MockSimControl mockSimControl;
|
MockSimControl mockSimControl;
|
||||||
MockXcode mockXcode;
|
Xcode xcode;
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
fakeProcessManager = FakeProcessManager.list(<FakeCommand>[]);
|
fakeProcessManager = FakeProcessManager.list(<FakeCommand>[]);
|
||||||
mockIosProject = MockIosProject();
|
mockIosProject = MockIosProject();
|
||||||
mockSimControl = MockSimControl();
|
mockSimControl = MockSimControl();
|
||||||
mockXcode = MockXcode();
|
xcode = Xcode.test(processManager: FakeProcessManager.any());
|
||||||
when(mockXcode.xcrunCommand()).thenReturn(<String>['xcrun']);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
group('syslog', () {
|
group('syslog', () {
|
||||||
@ -561,7 +530,7 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
|
|||||||
ProcessManager: () => fakeProcessManager,
|
ProcessManager: () => fakeProcessManager,
|
||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
Platform: () => osx,
|
Platform: () => osx,
|
||||||
Xcode: () => mockXcode,
|
Xcode: () => xcode,
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('simulator can output `)`', () async {
|
testUsingContext('simulator can output `)`', () async {
|
||||||
@ -597,7 +566,7 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
|
|||||||
ProcessManager: () => fakeProcessManager,
|
ProcessManager: () => fakeProcessManager,
|
||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
Platform: () => osx,
|
Platform: () => osx,
|
||||||
Xcode: () => mockXcode,
|
Xcode: () => xcode,
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('multiline messages', () async {
|
testUsingContext('multiline messages', () async {
|
||||||
@ -649,7 +618,7 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
|
|||||||
ProcessManager: () => fakeProcessManager,
|
ProcessManager: () => fakeProcessManager,
|
||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
Platform: () => osx,
|
Platform: () => osx,
|
||||||
Xcode: () => mockXcode,
|
Xcode: () => xcode,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -712,7 +681,6 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
|
|||||||
});
|
});
|
||||||
|
|
||||||
group('SimControl', () {
|
group('SimControl', () {
|
||||||
const int mockPid = 123;
|
|
||||||
const String validSimControlOutput = '''
|
const String validSimControlOutput = '''
|
||||||
{
|
{
|
||||||
"devices" : {
|
"devices" : {
|
||||||
@ -744,30 +712,34 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
|
|||||||
}
|
}
|
||||||
''';
|
''';
|
||||||
|
|
||||||
MockLogger mockLogger;
|
FakeProcessManager fakeProcessManager;
|
||||||
MockProcessManager mockProcessManager;
|
Xcode xcode;
|
||||||
MockXcode mockXcode;
|
|
||||||
SimControl simControl;
|
SimControl simControl;
|
||||||
const String deviceId = 'smart-phone';
|
const String deviceId = 'smart-phone';
|
||||||
const String appId = 'flutterApp';
|
const String appId = 'flutterApp';
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
mockLogger = MockLogger();
|
fakeProcessManager = FakeProcessManager.list(<FakeCommand>[]);
|
||||||
mockProcessManager = MockProcessManager();
|
xcode = Xcode.test(processManager: FakeProcessManager.any());
|
||||||
when(mockProcessManager.run(any)).thenAnswer((Invocation _) async {
|
|
||||||
return ProcessResult(mockPid, 0, validSimControlOutput, '');
|
|
||||||
});
|
|
||||||
|
|
||||||
mockXcode = MockXcode();
|
|
||||||
when(mockXcode.xcrunCommand()).thenReturn(<String>['xcrun']);
|
|
||||||
simControl = SimControl(
|
simControl = SimControl(
|
||||||
logger: mockLogger,
|
logger: BufferLogger.test(),
|
||||||
processManager: mockProcessManager,
|
processManager: fakeProcessManager,
|
||||||
xcode: mockXcode,
|
xcode: xcode,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('getDevices succeeds', () async {
|
testWithoutContext('getDevices succeeds', () async {
|
||||||
|
fakeProcessManager.addCommand(const FakeCommand(
|
||||||
|
command: <String>[
|
||||||
|
'xcrun',
|
||||||
|
'simctl',
|
||||||
|
'list',
|
||||||
|
'--json',
|
||||||
|
'devices',
|
||||||
|
],
|
||||||
|
stdout: validSimControlOutput,
|
||||||
|
));
|
||||||
|
|
||||||
final List<SimDevice> devices = await simControl.getDevices();
|
final List<SimDevice> devices = await simControl.getDevices();
|
||||||
|
|
||||||
final SimDevice watch = devices[0];
|
final SimDevice watch = devices[0];
|
||||||
@ -793,14 +765,25 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
|
|||||||
expect(tv.name, 'Apple TV');
|
expect(tv.name, 'Apple TV');
|
||||||
expect(tv.udid, 'TEST-TV-UDID');
|
expect(tv.udid, 'TEST-TV-UDID');
|
||||||
expect(tv.isBooted, isFalse);
|
expect(tv.isBooted, isFalse);
|
||||||
|
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('getDevices handles bad simctl output', () async {
|
testWithoutContext('getDevices handles bad simctl output', () async {
|
||||||
when(mockProcessManager.run(any))
|
fakeProcessManager.addCommand(const FakeCommand(
|
||||||
.thenAnswer((Invocation _) async => ProcessResult(mockPid, 0, 'Install Started', ''));
|
command: <String>[
|
||||||
|
'xcrun',
|
||||||
|
'simctl',
|
||||||
|
'list',
|
||||||
|
'--json',
|
||||||
|
'devices',
|
||||||
|
],
|
||||||
|
stdout: 'Install Started',
|
||||||
|
));
|
||||||
|
|
||||||
final List<SimDevice> devices = await simControl.getDevices();
|
final List<SimDevice> devices = await simControl.getDevices();
|
||||||
|
|
||||||
expect(devices, isEmpty);
|
expect(devices, isEmpty);
|
||||||
|
expect(fakeProcessManager.hasRemainingExpectations, isFalse);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('sdkMajorVersion defaults to 11 when sdkNameAndVersion is junk', () async {
|
testWithoutContext('sdkMajorVersion defaults to 11 when sdkNameAndVersion is junk', () async {
|
||||||
@ -815,11 +798,19 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('.install() handles exceptions', () async {
|
testWithoutContext('.install() handles exceptions', () async {
|
||||||
when(mockProcessManager.run(
|
fakeProcessManager.addCommand(FakeCommand(
|
||||||
<String>['xcrun', 'simctl', 'install', deviceId, appId],
|
command: const <String>[
|
||||||
environment: anyNamed('environment'),
|
'xcrun',
|
||||||
workingDirectory: anyNamed('workingDirectory'),
|
'simctl',
|
||||||
)).thenThrow(const ProcessException('xcrun', <String>[]));
|
'install',
|
||||||
|
deviceId,
|
||||||
|
appId,
|
||||||
|
],
|
||||||
|
onRun: () {
|
||||||
|
throw const ProcessException('xcrun', <String>[]);
|
||||||
|
},
|
||||||
|
));
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
() async => await simControl.install(deviceId, appId),
|
() async => await simControl.install(deviceId, appId),
|
||||||
throwsToolExit(message: r'Unable to install'),
|
throwsToolExit(message: r'Unable to install'),
|
||||||
@ -827,11 +818,19 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('.uninstall() handles exceptions', () async {
|
testWithoutContext('.uninstall() handles exceptions', () async {
|
||||||
when(mockProcessManager.run(
|
fakeProcessManager.addCommand(FakeCommand(
|
||||||
<String>['xcrun', 'simctl', 'uninstall', deviceId, appId],
|
command: const <String>[
|
||||||
environment: anyNamed('environment'),
|
'xcrun',
|
||||||
workingDirectory: anyNamed('workingDirectory'),
|
'simctl',
|
||||||
)).thenThrow(const ProcessException('xcrun', <String>[]));
|
'uninstall',
|
||||||
|
deviceId,
|
||||||
|
appId,
|
||||||
|
],
|
||||||
|
onRun: () {
|
||||||
|
throw const ProcessException('xcrun', <String>[]);
|
||||||
|
},
|
||||||
|
));
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
() async => await simControl.uninstall(deviceId, appId),
|
() async => await simControl.uninstall(deviceId, appId),
|
||||||
throwsToolExit(message: r'Unable to uninstall'),
|
throwsToolExit(message: r'Unable to uninstall'),
|
||||||
@ -839,11 +838,19 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWithoutContext('.launch() handles exceptions', () async {
|
testWithoutContext('.launch() handles exceptions', () async {
|
||||||
when(mockProcessManager.run(
|
fakeProcessManager.addCommand(FakeCommand(
|
||||||
<String>['xcrun', 'simctl', 'launch', deviceId, appId],
|
command: const <String>[
|
||||||
environment: anyNamed('environment'),
|
'xcrun',
|
||||||
workingDirectory: anyNamed('workingDirectory'),
|
'simctl',
|
||||||
)).thenThrow(const ProcessException('xcrun', <String>[]));
|
'launch',
|
||||||
|
deviceId,
|
||||||
|
appId,
|
||||||
|
],
|
||||||
|
onRun: () {
|
||||||
|
throw const ProcessException('xcrun', <String>[]);
|
||||||
|
},
|
||||||
|
));
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
() async => await simControl.launch(deviceId, appId),
|
() async => await simControl.launch(deviceId, appId),
|
||||||
throwsToolExit(message: r'Unable to launch'),
|
throwsToolExit(message: r'Unable to launch'),
|
||||||
@ -853,12 +860,11 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
|
|||||||
|
|
||||||
group('startApp', () {
|
group('startApp', () {
|
||||||
SimControl simControl;
|
SimControl simControl;
|
||||||
MockXcode mockXcode;
|
Xcode xcode;
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
simControl = MockSimControl();
|
simControl = MockSimControl();
|
||||||
mockXcode = MockXcode();
|
xcode = Xcode.test(processManager: FakeProcessManager.any());
|
||||||
when(mockXcode.xcrunCommand()).thenReturn(<String>['xcrun']);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext("startApp uses compiled app's Info.plist to find CFBundleIdentifier", () async {
|
testUsingContext("startApp uses compiled app's Info.plist to find CFBundleIdentifier", () async {
|
||||||
@ -882,7 +888,7 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
|
|||||||
PlistParser: () => MockPlistUtils(),
|
PlistParser: () => MockPlistUtils(),
|
||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
Xcode: () => mockXcode,
|
Xcode: () => xcode,
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('startApp respects the enable software rendering flag', () async {
|
testUsingContext('startApp respects the enable software rendering flag', () async {
|
||||||
@ -905,17 +911,17 @@ Dec 20 17:04:32 md32-11-vm1 Another App[88374]: Ignore this text'''
|
|||||||
PlistParser: () => MockPlistUtils(),
|
PlistParser: () => MockPlistUtils(),
|
||||||
FileSystem: () => fileSystem,
|
FileSystem: () => fileSystem,
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
Xcode: () => mockXcode,
|
Xcode: () => xcode,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group('IOSDevice.isSupportedForProject', () {
|
group('IOSDevice.isSupportedForProject', () {
|
||||||
MockSimControl mockSimControl;
|
MockSimControl mockSimControl;
|
||||||
MockXcode mockXcode;
|
Xcode xcode;
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
mockSimControl = MockSimControl();
|
mockSimControl = MockSimControl();
|
||||||
mockXcode = MockXcode();
|
xcode = Xcode.test(processManager: FakeProcessManager.any());
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('is true on module project', () async {
|
testUsingContext('is true on module project', () async {
|
||||||
@ -938,7 +944,7 @@ flutter:
|
|||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
FileSystem: () => MemoryFileSystem.test(),
|
FileSystem: () => MemoryFileSystem.test(),
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
Xcode: () => mockXcode,
|
Xcode: () => xcode,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -956,7 +962,7 @@ flutter:
|
|||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
FileSystem: () => MemoryFileSystem.test(),
|
FileSystem: () => MemoryFileSystem.test(),
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
Xcode: () => mockXcode,
|
Xcode: () => xcode,
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('is false with no host app and no module', () async {
|
testUsingContext('is false with no host app and no module', () async {
|
||||||
@ -972,7 +978,7 @@ flutter:
|
|||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
FileSystem: () => MemoryFileSystem.test(),
|
FileSystem: () => MemoryFileSystem.test(),
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
Xcode: () => mockXcode,
|
Xcode: () => xcode,
|
||||||
});
|
});
|
||||||
|
|
||||||
testUsingContext('createDevFSWriter returns a LocalDevFSWriter', () {
|
testUsingContext('createDevFSWriter returns a LocalDevFSWriter', () {
|
||||||
|
@ -306,12 +306,12 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
group('language', () {
|
group('language', () {
|
||||||
MockXcodeProjectInterpreter mockXcodeProjectInterpreter;
|
XcodeProjectInterpreter xcodeProjectInterpreter;
|
||||||
MemoryFileSystem fs;
|
MemoryFileSystem fs;
|
||||||
FlutterProjectFactory flutterProjectFactory;
|
FlutterProjectFactory flutterProjectFactory;
|
||||||
setUp(() {
|
setUp(() {
|
||||||
fs = MemoryFileSystem.test();
|
fs = MemoryFileSystem.test();
|
||||||
mockXcodeProjectInterpreter = MockXcodeProjectInterpreter();
|
xcodeProjectInterpreter = XcodeProjectInterpreter.test(processManager: FakeProcessManager.any());
|
||||||
flutterProjectFactory = FlutterProjectFactory(
|
flutterProjectFactory = FlutterProjectFactory(
|
||||||
logger: logger,
|
logger: logger,
|
||||||
fileSystem: fs,
|
fileSystem: fs,
|
||||||
@ -337,7 +337,7 @@ apply plugin: 'kotlin-android'
|
|||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
FileSystem: () => fs,
|
FileSystem: () => fs,
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
|
XcodeProjectInterpreter: () => xcodeProjectInterpreter,
|
||||||
FlutterProjectFactory: () => flutterProjectFactory,
|
FlutterProjectFactory: () => flutterProjectFactory,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user