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

Adopt FakeProcess, remove MockProcess (#76276)

parent 1bf66833
...@@ -20,7 +20,7 @@ import 'package:mockito/mockito.dart'; ...@@ -20,7 +20,7 @@ import 'package:mockito/mockito.dart';
import '../../src/common.dart'; import '../../src/common.dart';
import '../../src/context.dart'; import '../../src/context.dart';
import '../../src/fakes.dart'; import '../../src/fakes.dart';
import '../../src/mocks.dart' show MockAndroidSdk, MockProcess, MockProcessManager; import '../../src/mocks.dart' show MockAndroidSdk, MockProcessManager;
import '../../src/testbed.dart'; import '../../src/testbed.dart';
class MockAndroidSdkVersion extends Mock implements AndroidSdkVersion {} class MockAndroidSdkVersion extends Mock implements AndroidSdkVersion {}
...@@ -41,10 +41,10 @@ void main() { ...@@ -41,10 +41,10 @@ void main() {
stdio = FakeStdio(); stdio = FakeStdio();
}); });
MockProcess Function(List<String>) processMetaFactory(List<String> stdout) { FakeProcess Function(List<String>) processMetaFactory(List<String> stdout) {
final Stream<List<int>> stdoutStream = Stream<List<int>>.fromIterable( final Stream<List<int>> stdoutStream = Stream<List<int>>.fromIterable(
stdout.map<List<int>>((String s) => s.codeUnits)); stdout.map<List<int>>((String s) => s.codeUnits));
return (List<String> command) => MockProcess(stdout: stdoutStream); return (List<String> command) => FakeProcess(stdout: stdoutStream);
} }
testWithoutContext('AndroidWorkflow handles a null AndroidSDK', () { testWithoutContext('AndroidWorkflow handles a null AndroidSDK', () {
......
...@@ -16,8 +16,7 @@ import 'package:fake_async/fake_async.dart'; ...@@ -16,8 +16,7 @@ import 'package:fake_async/fake_async.dart';
import '../../src/common.dart'; import '../../src/common.dart';
import '../../src/context.dart'; import '../../src/context.dart';
import '../../src/fakes.dart'; import '../../src/fakes.dart';
import '../../src/mocks.dart' show MockProcess, import '../../src/mocks.dart' show MockProcessManager,
MockProcessManager,
flakyProcessFactory; flakyProcessFactory;
void main() { void main() {
...@@ -101,7 +100,7 @@ void main() { ...@@ -101,7 +100,7 @@ void main() {
); );
}); });
MockProcess Function(List<String>) processMetaFactory(List<String> stdout, { FakeProcess Function(List<String>) processMetaFactory(List<String> stdout, {
List<String> stderr = const <String>[], List<String> stderr = const <String>[],
}) { }) {
final Stream<List<int>> stdoutStream = Stream<List<int>>.fromIterable( final Stream<List<int>> stdoutStream = Stream<List<int>>.fromIterable(
...@@ -110,7 +109,7 @@ void main() { ...@@ -110,7 +109,7 @@ void main() {
final Stream<List<int>> stderrStream = Stream<List<int>>.fromIterable( final Stream<List<int>> stderrStream = Stream<List<int>>.fromIterable(
stderr.map<List<int>>((String s) => s.codeUnits, stderr.map<List<int>>((String s) => s.codeUnits,
)); ));
return (List<String> command) => MockProcess(stdout: stdoutStream, stderr: stderrStream); return (List<String> command) => FakeProcess(stdout: stdoutStream, stderr: stderrStream);
} }
testWithoutContext('Command output is not wrapped.', () async { testWithoutContext('Command output is not wrapped.', () async {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
// @dart = 2.8 // @dart = 2.8
import 'package:flutter_tools/src/base/common.dart'; import 'package:flutter_tools/src/base/common.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/base/terminal.dart'; import 'package:flutter_tools/src/base/terminal.dart';
import 'package:flutter_tools/src/base/user_messages.dart'; import 'package:flutter_tools/src/base/user_messages.dart';
...@@ -19,7 +20,6 @@ import '../src/common.dart'; ...@@ -19,7 +20,6 @@ import '../src/common.dart';
import '../src/context.dart'; import '../src/context.dart';
import '../src/fake_devices.dart'; import '../src/fake_devices.dart';
import '../src/fakes.dart'; import '../src/fakes.dart';
import '../src/mocks.dart';
void main() { void main() {
group('DeviceManager', () { group('DeviceManager', () {
...@@ -555,3 +555,4 @@ class TestDeviceManager extends DeviceManager { ...@@ -555,3 +555,4 @@ class TestDeviceManager extends DeviceManager {
class MockTerminal extends Mock implements AnsiTerminal {} class MockTerminal extends Mock implements AnsiTerminal {}
class MockDeviceDiscovery extends Mock implements DeviceDiscovery {} class MockDeviceDiscovery extends Mock implements DeviceDiscovery {}
class FakeFlutterProject extends Fake implements FlutterProject {} class FakeFlutterProject extends Fake implements FlutterProject {}
class MockProcess extends Mock implements Process {}
...@@ -26,7 +26,7 @@ import '../src/context.dart'; ...@@ -26,7 +26,7 @@ import '../src/context.dart';
void main() { void main() {
FakePlatform platform; FakePlatform platform;
FileSystem fileSystem; FileSystem fileSystem;
ProcessManager processManager; FakeProcessManager processManager;
FlutterTesterTestDevice device; FlutterTesterTestDevice device;
setUp(() { setUp(() {
...@@ -53,7 +53,7 @@ void main() { ...@@ -53,7 +53,7 @@ void main() {
group('The FLUTTER_TEST environment variable is passed to the test process', () { group('The FLUTTER_TEST environment variable is passed to the test process', () {
setUp(() { setUp(() {
processManager = MockProcessManager(); processManager = FakeProcessManager.list(<FakeCommand>[]);
device = createDevice(); device = createDevice();
fileSystem fileSystem
...@@ -62,55 +62,65 @@ void main() { ...@@ -62,55 +62,65 @@ void main() {
..writeAsStringSync('{"configVersion":2,"packages":[]}'); ..writeAsStringSync('{"configVersion":2,"packages":[]}');
}); });
Future<Map<String, String>> captureEnvironment() async { FakeCommand flutterTestCommand(String expectedFlutterTestValue) {
final Future<StreamChannel<String>> deviceStarted = device.start( return FakeCommand(command: const <String>[
compiledEntrypointPath: 'example.dill', '/',
); '--disable-observatory',
'--ipv6',
when(processManager.start( '--enable-checked-mode',
any, '--verify-entry-points',
environment: anyNamed('environment')), '--enable-software-rendering',
).thenAnswer((_) { '--skia-deterministic-rendering',
return Future<Process>.value(MockProcess()); '--enable-dart-profiling',
'--non-interactive',
'--use-test-fonts',
'--packages=.dart_tool/package_config.json',
'example.dill'
], environment: <String, String>{
'FLUTTER_TEST': expectedFlutterTestValue,
'FONTCONFIG_FILE': device.fontConfigManager.fontConfigFile.path,
'SERVER_PORT': 'null',
'APP_NAME': '',
}); });
await untilCalled(processManager.start(any, environment: anyNamed('environment')));
final VerificationResult toVerify = verify(processManager.start(
any,
environment: captureAnyNamed('environment'),
));
expect(toVerify.captured, hasLength(1));
expect(toVerify.captured.first, isA<Map<String, String>>());
await deviceStarted;
return toVerify.captured.first as Map<String, String>;
} }
testUsingContext('as true when not originally set', () async { testUsingContext('as true when not originally set', () async {
final Map<String, String> capturedEnvironment = await captureEnvironment(); processManager.addCommand(flutterTestCommand('true'));
expect(capturedEnvironment['FLUTTER_TEST'], 'true');
await device.start(compiledEntrypointPath: 'example.dill');
expect(processManager.hasRemainingExpectations, isFalse);
}); });
testUsingContext('as true when set to true', () async { testUsingContext('as true when set to true', () async {
platform.environment = <String, String>{'FLUTTER_TEST': 'true'}; platform.environment = <String, String>{'FLUTTER_TEST': 'true'};
final Map<String, String> capturedEnvironment = await captureEnvironment(); processManager.addCommand(flutterTestCommand('true'));
expect(capturedEnvironment['FLUTTER_TEST'], 'true');
await device.start(compiledEntrypointPath: 'example.dill');
expect(processManager.hasRemainingExpectations, isFalse);
}); });
testUsingContext('as false when set to false', () async { testUsingContext('as false when set to false', () async {
platform.environment = <String, String>{'FLUTTER_TEST': 'false'}; platform.environment = <String, String>{'FLUTTER_TEST': 'false'};
final Map<String, String> capturedEnvironment = await captureEnvironment(); processManager.addCommand(flutterTestCommand('false'));
expect(capturedEnvironment['FLUTTER_TEST'], 'false');
await device.start(compiledEntrypointPath: 'example.dill');
expect(processManager.hasRemainingExpectations, isFalse);
}); });
testUsingContext('unchanged when set', () async { testUsingContext('unchanged when set', () async {
platform.environment = <String, String>{'FLUTTER_TEST': 'neither true nor false'}; platform.environment = <String, String>{'FLUTTER_TEST': 'neither true nor false'};
final Map<String, String> capturedEnvironment = await captureEnvironment(); processManager.addCommand(flutterTestCommand('neither true nor false'));
expect(capturedEnvironment['FLUTTER_TEST'], 'neither true nor false');
await device.start(compiledEntrypointPath: 'example.dill');
expect(processManager.hasRemainingExpectations, isFalse);
}); });
testUsingContext('as null when set to null', () async { testUsingContext('as null when set to null', () async {
platform.environment = <String, String>{'FLUTTER_TEST': null}; platform.environment = <String, String>{'FLUTTER_TEST': null};
final Map<String, String> capturedEnvironment = await captureEnvironment(); processManager.addCommand(flutterTestCommand(null));
expect(capturedEnvironment['FLUTTER_TEST'], null);
await device.start(compiledEntrypointPath: 'example.dill');
expect(processManager.hasRemainingExpectations, isFalse);
}); });
}); });
...@@ -145,7 +155,7 @@ void main() { ...@@ -145,7 +155,7 @@ void main() {
testUsingContext('Can pass additional arguments to tester binary', () async { testUsingContext('Can pass additional arguments to tester binary', () async {
await device.start(compiledEntrypointPath: 'example.dill'); await device.start(compiledEntrypointPath: 'example.dill');
expect((processManager as FakeProcessManager).hasRemainingExpectations, false); expect(processManager.hasRemainingExpectations, false);
}); });
}); });
...@@ -201,7 +211,7 @@ class TestFlutterTesterDevice extends FlutterTesterTestDevice { ...@@ -201,7 +211,7 @@ class TestFlutterTesterDevice extends FlutterTesterTestDevice {
platform: platform, platform: platform,
fileSystem: fileSystem, fileSystem: fileSystem,
processManager: processManager, processManager: processManager,
logger: MockLogger(), logger: BufferLogger.test(),
debuggingOptions: DebuggingOptions.enabled( debuggingOptions: DebuggingOptions.enabled(
const BuildInfo( const BuildInfo(
BuildMode.debug, BuildMode.debug,
...@@ -246,20 +256,4 @@ class TestFlutterTesterDevice extends FlutterTesterTestDevice { ...@@ -246,20 +256,4 @@ class TestFlutterTesterDevice extends FlutterTesterTestDevice {
} }
class MockDartDevelopmentService extends Mock implements DartDevelopmentService {} class MockDartDevelopmentService extends Mock implements DartDevelopmentService {}
class MockHttpServer extends Mock implements HttpServer {} class MockHttpServer extends Mock implements HttpServer {}
class MockLogger extends Mock implements Logger {}
class MockProcessManager extends Mock implements ProcessManager {}
class MockProcess extends Mock implements Process {
@override
Future<int> get exitCode async => 0;
@override
Stream<List<int>> get stdout => const Stream<List<int>>.empty();
@override
Stream<List<int>> get stderr => const Stream<List<int>>.empty();
}
...@@ -28,7 +28,6 @@ import 'package:mockito/mockito.dart'; ...@@ -28,7 +28,6 @@ import 'package:mockito/mockito.dart';
import '../../src/common.dart'; import '../../src/common.dart';
import '../../src/context.dart'; import '../../src/context.dart';
import '../../src/mocks.dart';
void main() { void main() {
final FakePlatform macPlatform = FakePlatform(operatingSystem: 'macos'); final FakePlatform macPlatform = FakePlatform(operatingSystem: 'macos');
...@@ -584,3 +583,4 @@ void main() { ...@@ -584,3 +583,4 @@ void main() {
class MockIOSApp extends Mock implements IOSApp {} class MockIOSApp extends Mock implements IOSApp {}
class MockIOSWorkflow extends Mock implements IOSWorkflow {} class MockIOSWorkflow extends Mock implements IOSWorkflow {}
class MockXcdevice extends Mock implements XCDevice {} class MockXcdevice extends Mock implements XCDevice {}
class MockProcess extends Mock implements Process {}
...@@ -12,7 +12,6 @@ import 'package:flutter_tools/src/test/flutter_web_goldens.dart'; ...@@ -12,7 +12,6 @@ import 'package:flutter_tools/src/test/flutter_web_goldens.dart';
import '../../src/common.dart'; import '../../src/common.dart';
import '../../src/fakes.dart'; import '../../src/fakes.dart';
import '../../src/mocks.dart';
import '../../src/testbed.dart'; import '../../src/testbed.dart';
void main() { void main() {
...@@ -23,14 +22,14 @@ void main() { ...@@ -23,14 +22,14 @@ void main() {
Uri goldenKey; Uri goldenKey;
File imageFile2; File imageFile2;
Uri goldenKey2; Uri goldenKey2;
MockProcess Function(String) createMockProcess; FakeProcess Function(String) createFakeProcess;
setUpAll(() { setUpAll(() {
imageFile = globals.fs.file('test_image_file'); imageFile = globals.fs.file('test_image_file');
goldenKey = Uri.parse('file://golden_key'); goldenKey = Uri.parse('file://golden_key');
imageFile2 = globals.fs.file('second_test_image_file'); imageFile2 = globals.fs.file('second_test_image_file');
goldenKey2 = Uri.parse('file://second_golden_key'); goldenKey2 = Uri.parse('file://second_golden_key');
createMockProcess = (String stdout) => MockProcess( createFakeProcess = (String stdout) => FakeProcess(
exitCode: Future<int>.value(0), exitCode: Future<int>.value(0),
stdout: stdoutFromString(stdout), stdout: stdoutFromString(stdout),
); );
...@@ -42,7 +41,7 @@ void main() { ...@@ -42,7 +41,7 @@ void main() {
'message': 'some message', 'message': 'some message',
}; };
final MockProcess mockProcess = createMockProcess(jsonEncode(expectedResponse) + '\n'); final FakeProcess mockProcess = createFakeProcess(jsonEncode(expectedResponse) + '\n');
final MemoryIOSink ioSink = mockProcess.stdin as MemoryIOSink; final MemoryIOSink ioSink = mockProcess.stdin as MemoryIOSink;
final TestGoldenComparatorProcess process = TestGoldenComparatorProcess(mockProcess); final TestGoldenComparatorProcess process = TestGoldenComparatorProcess(mockProcess);
...@@ -65,7 +64,7 @@ void main() { ...@@ -65,7 +64,7 @@ void main() {
'message': 'some other message', 'message': 'some other message',
}; };
final MockProcess mockProcess = createMockProcess(jsonEncode(expectedResponse1) + '\n' + jsonEncode(expectedResponse2) + '\n'); final FakeProcess mockProcess = createFakeProcess(jsonEncode(expectedResponse1) + '\n' + jsonEncode(expectedResponse2) + '\n');
final MemoryIOSink ioSink = mockProcess.stdin as MemoryIOSink; final MemoryIOSink ioSink = mockProcess.stdin as MemoryIOSink;
final TestGoldenComparatorProcess process = TestGoldenComparatorProcess(mockProcess); final TestGoldenComparatorProcess process = TestGoldenComparatorProcess(mockProcess);
...@@ -89,7 +88,7 @@ void main() { ...@@ -89,7 +88,7 @@ void main() {
'message': 'some message', 'message': 'some message',
}; };
final MockProcess mockProcess = createMockProcess(''' final FakeProcess mockProcess = createFakeProcess('''
Some random data including {} curly bracket Some random data including {} curly bracket
{} curly bracket that is not on the beginning of the line {} curly bracket that is not on the beginning of the line
${jsonEncode(expectedResponse)} ${jsonEncode(expectedResponse)}
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'dart:io' as io show IOSink;
import 'package:flutter_tools/src/android/android_device.dart'; import 'package:flutter_tools/src/android/android_device.dart';
import 'package:flutter_tools/src/android/android_sdk.dart' show AndroidSdk; import 'package:flutter_tools/src/android/android_sdk.dart' show AndroidSdk;
...@@ -83,11 +82,11 @@ ro.build.version.codename=REL ...@@ -83,11 +82,11 @@ ro.build.version.codename=REL
} }
/// A strategy for creating Process objects from a list of commands. /// A strategy for creating Process objects from a list of commands.
typedef ProcessFactory = Process Function(List<String> command); typedef _ProcessFactory = Process Function(List<String> command);
/// A ProcessManager that starts Processes by delegating to a ProcessFactory. /// A ProcessManager that starts Processes by delegating to a ProcessFactory.
class MockProcessManager extends Mock implements ProcessManager { class MockProcessManager extends Mock implements ProcessManager {
ProcessFactory processFactory = (List<String> commands) => MockProcess(); _ProcessFactory processFactory = (List<String> commands) => FakeProcess();
bool canRunSucceeds = true; bool canRunSucceeds = true;
bool runSucceeds = true; bool runSucceeds = true;
List<String> commands; List<String> commands;
...@@ -119,7 +118,7 @@ class MockProcessManager extends Mock implements ProcessManager { ...@@ -119,7 +118,7 @@ class MockProcessManager extends Mock implements ProcessManager {
/// A function that generates a process factory that gives processes that fail /// A function that generates a process factory that gives processes that fail
/// a given number of times before succeeding. The returned processes will /// a given number of times before succeeding. The returned processes will
/// fail after a delay if one is supplied. /// fail after a delay if one is supplied.
ProcessFactory flakyProcessFactory({ _ProcessFactory flakyProcessFactory({
int flakes, int flakes,
bool Function(List<String> command) filter, bool Function(List<String> command) filter,
Duration delay, Duration delay,
...@@ -131,10 +130,10 @@ ProcessFactory flakyProcessFactory({ ...@@ -131,10 +130,10 @@ ProcessFactory flakyProcessFactory({
stderr ??= () => const Stream<List<int>>.empty(); stderr ??= () => const Stream<List<int>>.empty();
return (List<String> command) { return (List<String> command) {
if (filter != null && !filter(command)) { if (filter != null && !filter(command)) {
return MockProcess(); return FakeProcess();
} }
if (flakesLeft == 0) { if (flakesLeft == 0) {
return MockProcess( return FakeProcess(
exitCode: Future<int>.value(0), exitCode: Future<int>.value(0),
stdout: stdout(), stdout: stdout(),
stderr: stderr(), stderr: stderr(),
...@@ -147,7 +146,7 @@ ProcessFactory flakyProcessFactory({ ...@@ -147,7 +146,7 @@ ProcessFactory flakyProcessFactory({
} else { } else {
exitFuture = Future<int>.delayed(delay, () => Future<int>.value(-9)); exitFuture = Future<int>.delayed(delay, () => Future<int>.value(-9));
} }
return MockProcess( return FakeProcess(
exitCode: exitFuture, exitCode: exitFuture,
stdout: stdout(), stdout: stdout(),
stderr: stderr(), stderr: stderr(),
...@@ -173,33 +172,6 @@ Process createMockProcess({ int exitCode = 0, String stdout = '', String stderr ...@@ -173,33 +172,6 @@ Process createMockProcess({ int exitCode = 0, String stdout = '', String stderr
class _MockBasicProcess extends Mock implements Process {} class _MockBasicProcess extends Mock implements Process {}
/// A process that exits successfully with no output and ignores all input.
class MockProcess extends Mock implements Process {
MockProcess({
this.pid = 1,
Future<int> exitCode,
Stream<List<int>> stdin,
this.stdout = const Stream<List<int>>.empty(),
this.stderr = const Stream<List<int>>.empty(),
}) : exitCode = exitCode ?? Future<int>.value(0),
stdin = stdin as IOSink ?? MemoryIOSink();
@override
final int pid;
@override
final Future<int> exitCode;
@override
final io.IOSink stdin;
@override
final Stream<List<int>> stdout;
@override
final Stream<List<int>> stderr;
}
class MockIosProject extends Mock implements IosProject { class MockIosProject extends Mock implements IosProject {
static const String bundleId = 'com.example.test'; static const String bundleId = 'com.example.test';
static const String appBundleName = 'My Super Awesome App.app'; static const String appBundleName = 'My Super Awesome App.app';
......
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