// 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 environment = {}; @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> _stdoutController = StreamController>(); final StreamController> _stderrController = StreamController>(); final MockIOSink stdinMock = MockIOSink(); @override int get pid => 99; @override Future get exitCode async => _exitCode; @override Stream> get stdout => _stdoutController.stream; @override Stream> 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 lines = []; @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 arguments = invocation.positionalArguments[0]! as List; final String gitCommand = arguments.removeAt(0); return processRunner.run('git-$gitCommand', arguments); }); return gitDir; }