| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'dart:async'; |
| import 'dart:convert'; |
| import 'dart:io' as io; |
| |
| import 'package:file/file.dart'; |
| import 'package:flutter_plugin_tools/src/common/process_runner.dart'; |
| import 'package:mockito/mockito.dart'; |
| import 'package:platform/platform.dart'; |
| |
| import 'common/package_command_test.mocks.dart'; |
| |
| class MockPlatform extends Mock implements Platform { |
| MockPlatform({ |
| this.isLinux = false, |
| this.isMacOS = false, |
| this.isWindows = false, |
| }); |
| |
| @override |
| bool isLinux; |
| |
| @override |
| bool isMacOS; |
| |
| @override |
| bool isWindows; |
| |
| @override |
| Uri get script => isWindows |
| ? Uri.file(r'C:\foo\bar', windows: true) |
| : Uri.file('/foo/bar', windows: false); |
| |
| @override |
| Map<String, String> environment = <String, String>{}; |
| |
| @override |
| String get pathSeparator => isWindows ? r'\' : '/'; |
| } |
| |
| class MockProcess extends Mock implements io.Process { |
| /// Creates a mock process with the given results. |
| /// |
| /// The default encodings match the ProcessRunner defaults; mocks for |
| /// processes run with a different encoding will need to be created with |
| /// the matching encoding. |
| MockProcess({ |
| int exitCode = 0, |
| String? stdout, |
| String? stderr, |
| Encoding stdoutEncoding = io.systemEncoding, |
| Encoding stderrEncoding = io.systemEncoding, |
| }) : _exitCode = exitCode { |
| if (stdout != null) { |
| _stdoutController.add(stdoutEncoding.encoder.convert(stdout)); |
| } |
| if (stderr != null) { |
| _stderrController.add(stderrEncoding.encoder.convert(stderr)); |
| } |
| _stdoutController.close(); |
| _stderrController.close(); |
| } |
| |
| final int _exitCode; |
| final StreamController<List<int>> _stdoutController = |
| StreamController<List<int>>(); |
| final StreamController<List<int>> _stderrController = |
| StreamController<List<int>>(); |
| final MockIOSink stdinMock = MockIOSink(); |
| |
| @override |
| int get pid => 99; |
| |
| @override |
| Future<int> get exitCode async => _exitCode; |
| |
| @override |
| Stream<List<int>> get stdout => _stdoutController.stream; |
| |
| @override |
| Stream<List<int>> get stderr => _stderrController.stream; |
| |
| @override |
| IOSink get stdin => stdinMock; |
| |
| @override |
| bool kill([io.ProcessSignal signal = io.ProcessSignal.sigterm]) => true; |
| } |
| |
| class MockIOSink extends Mock implements IOSink { |
| List<String> lines = <String>[]; |
| |
| @override |
| void writeln([Object? obj = '']) => lines.add(obj.toString()); |
| } |
| |
| /// Creates a mockGitDir that uses [packagesDir]'s parent as its root, and |
| /// forwards any git commands to [processRunner] to make it easy to mock their |
| /// output the same way other process calls are mocked. |
| /// |
| /// The first argument to any `git` command is added to the command to make |
| /// targeting the mock results easier. For example, `git ls ...` will become |
| /// a `git-ls ...` call to [processRunner]. |
| /// |
| MockGitDir createForwardingMockGitDir({ |
| required Directory packagesDir, |
| required ProcessRunner processRunner, |
| }) { |
| final MockGitDir gitDir = MockGitDir(); |
| when(gitDir.path).thenReturn(packagesDir.parent.path); |
| when(gitDir.runCommand(any, throwOnError: anyNamed('throwOnError'))) |
| .thenAnswer((Invocation invocation) { |
| final List<String> arguments = |
| invocation.positionalArguments[0]! as List<String>; |
| final String gitCommand = arguments.removeAt(0); |
| return processRunner.run('git-$gitCommand', arguments); |
| }); |
| return gitDir; |
| } |