// Mocks generated by Mockito 5.0.7 from annotations
// in flutter_plugin_tools/test/common_test.dart.
// Do not manually edit this file.

import 'dart:async' as _i6;
import 'dart:io' as _i4;

import 'package:git/src/branch_reference.dart' as _i3;
import 'package:git/src/commit.dart' as _i2;
import 'package:git/src/commit_reference.dart' as _i8;
import 'package:git/src/git_dir.dart' as _i5;
import 'package:git/src/tag.dart' as _i7;
import 'package:git/src/tree_entry.dart' as _i9;
import 'package:mockito/mockito.dart' as _i1;

// ignore_for_file: comment_references
// ignore_for_file: unnecessary_parenthesis

// ignore_for_file: prefer_const_constructors

// ignore_for_file: avoid_redundant_argument_values

class _FakeCommit extends _i1.Fake implements _i2.Commit {}

class _FakeBranchReference extends _i1.Fake implements _i3.BranchReference {}

class _FakeProcessResult extends _i1.Fake implements _i4.ProcessResult {}

/// A class which mocks [GitDir].
///
/// See the documentation for Mockito's code generation for more information.
class MockGitDir extends _i1.Mock implements _i5.GitDir {
  MockGitDir() {
    _i1.throwOnMissingStub(this);
  }

  @override
  String get path =>
      (super.noSuchMethod(Invocation.getter(#path), returnValue: '') as String);
  @override
  _i6.Future<int> commitCount([String? branchName = r'HEAD']) =>
      (super.noSuchMethod(Invocation.method(#commitCount, [branchName]),
          returnValue: Future<int>.value(0)) as _i6.Future<int>);
  @override
  _i6.Future<_i2.Commit> commitFromRevision(String? revision) =>
      (super.noSuchMethod(Invocation.method(#commitFromRevision, [revision]),
              returnValue: Future<_i2.Commit>.value(_FakeCommit()))
          as _i6.Future<_i2.Commit>);
  @override
  _i6.Future<Map<String, _i2.Commit>> commits([String? branchName = r'HEAD']) =>
      (super.noSuchMethod(Invocation.method(#commits, [branchName]),
              returnValue:
                  Future<Map<String, _i2.Commit>>.value(<String, _i2.Commit>{}))
          as _i6.Future<Map<String, _i2.Commit>>);
  @override
  _i6.Future<_i3.BranchReference?> branchReference(String? branchName) =>
      (super.noSuchMethod(Invocation.method(#branchReference, [branchName]),
              returnValue:
                  Future<_i3.BranchReference?>.value(_FakeBranchReference()))
          as _i6.Future<_i3.BranchReference?>);
  @override
  _i6.Future<List<_i3.BranchReference>> branches() => (super.noSuchMethod(
          Invocation.method(#branches, []),
          returnValue:
              Future<List<_i3.BranchReference>>.value(<_i3.BranchReference>[]))
      as _i6.Future<List<_i3.BranchReference>>);
  @override
  _i6.Stream<_i7.Tag> tags() =>
      (super.noSuchMethod(Invocation.method(#tags, []),
          returnValue: Stream<_i7.Tag>.empty()) as _i6.Stream<_i7.Tag>);
  @override
  _i6.Future<List<_i8.CommitReference>> showRef(
          {bool? heads = false, bool? tags = false}) =>
      (super.noSuchMethod(
              Invocation.method(#showRef, [], {#heads: heads, #tags: tags}),
              returnValue: Future<List<_i8.CommitReference>>.value(
                  <_i8.CommitReference>[]))
          as _i6.Future<List<_i8.CommitReference>>);
  @override
  _i6.Future<_i3.BranchReference> currentBranch() =>
      (super.noSuchMethod(Invocation.method(#currentBranch, []),
              returnValue:
                  Future<_i3.BranchReference>.value(_FakeBranchReference()))
          as _i6.Future<_i3.BranchReference>);
  @override
  _i6.Future<List<_i9.TreeEntry>> lsTree(String? treeish,
          {bool? subTreesOnly = false, String? path}) =>
      (super.noSuchMethod(
              Invocation.method(#lsTree, [treeish],
                  {#subTreesOnly: subTreesOnly, #path: path}),
              returnValue: Future<List<_i9.TreeEntry>>.value(<_i9.TreeEntry>[]))
          as _i6.Future<List<_i9.TreeEntry>>);
  @override
  _i6.Future<String?> createOrUpdateBranch(
          String? branchName, String? treeSha, String? commitMessage) =>
      (super.noSuchMethod(
          Invocation.method(
              #createOrUpdateBranch, [branchName, treeSha, commitMessage]),
          returnValue: Future<String?>.value('')) as _i6.Future<String?>);
  @override
  _i6.Future<String> commitTree(String? treeSha, String? commitMessage,
          {List<String>? parentCommitShas}) =>
      (super.noSuchMethod(
          Invocation.method(#commitTree, [treeSha, commitMessage],
              {#parentCommitShas: parentCommitShas}),
          returnValue: Future<String>.value('')) as _i6.Future<String>);
  @override
  _i6.Future<Map<String, String>> writeObjects(List<String>? paths) =>
      (super.noSuchMethod(Invocation.method(#writeObjects, [paths]),
              returnValue:
                  Future<Map<String, String>>.value(<String, String>{}))
          as _i6.Future<Map<String, String>>);
  @override
  _i6.Future<_i4.ProcessResult> runCommand(Iterable<String>? args,
          {bool? throwOnError = true}) =>
      (super.noSuchMethod(
          Invocation.method(#runCommand, [args], {#throwOnError: throwOnError}),
          returnValue:
              Future<_i4.ProcessResult>.value(_FakeProcessResult())) as _i6
          .Future<_i4.ProcessResult>);
  @override
  _i6.Future<bool> isWorkingTreeClean() =>
      (super.noSuchMethod(Invocation.method(#isWorkingTreeClean, []),
          returnValue: Future<bool>.value(false)) as _i6.Future<bool>);
  @override
  _i6.Future<_i2.Commit?> updateBranch(
          String? branchName,
          _i6.Future<dynamic> Function(_i4.Directory)? populater,
          String? commitMessage) =>
      (super.noSuchMethod(
              Invocation.method(
                  #updateBranch, [branchName, populater, commitMessage]),
              returnValue: Future<_i2.Commit?>.value(_FakeCommit()))
          as _i6.Future<_i2.Commit?>);
  @override
  _i6.Future<_i2.Commit?> updateBranchWithDirectoryContents(String? branchName,
          String? sourceDirectoryPath, String? commitMessage) =>
      (super.noSuchMethod(
              Invocation.method(#updateBranchWithDirectoryContents,
                  [branchName, sourceDirectoryPath, commitMessage]),
              returnValue: Future<_i2.Commit?>.value(_FakeCommit()))
          as _i6.Future<_i2.Commit?>);
}
