From 78328ae976100aa993e6e3e84b373c0fb5114baf Mon Sep 17 00:00:00 2001 From: Geoff Lamrock Date: Thu, 19 Dec 2024 16:36:09 +1100 Subject: [PATCH] Use proper Git repository for cleanup stack tests (#146) --- .../Stack/CleanupStackCommandHandlerTests.cs | 174 ++++++++++-------- .../Helpers/TestGitRepositoryBuilder.cs | 22 ++- 2 files changed, 113 insertions(+), 83 deletions(-) diff --git a/src/Stack.Tests/Commands/Stack/CleanupStackCommandHandlerTests.cs b/src/Stack.Tests/Commands/Stack/CleanupStackCommandHandlerTests.cs index d4f10a2..1c17622 100644 --- a/src/Stack.Tests/Commands/Stack/CleanupStackCommandHandlerTests.cs +++ b/src/Stack.Tests/Commands/Stack/CleanupStackCommandHandlerTests.cs @@ -15,25 +15,29 @@ public class CleanupStackCommandHandlerTests public async Task WhenBranchExistsLocally_ButNotInRemote_BranchIsDeletedLocally() { // Arrange - var gitOperations = Substitute.For(); - var gitHubOperations = Substitute.For(); + var sourceBranch = Some.BranchName(); + var branchToCleanup = Some.BranchName(); + var branchToKeep = Some.BranchName(); + using var repo = new TestGitRepositoryBuilder() + .WithBranch(sourceBranch, true) + .WithBranch(branchToCleanup, false) + .WithBranch(branchToKeep, true) + .Build(); + var stackConfig = Substitute.For(); var inputProvider = Substitute.For(); var outputProvider = Substitute.For(); + var gitOperations = new GitOperations(outputProvider, repo.GitOperationSettings); + var gitHubOperations = Substitute.For(); var handler = new CleanupStackCommandHandler(inputProvider, outputProvider, gitOperations, gitHubOperations, stackConfig); - var remoteUri = Some.HttpsUri().ToString(); - - gitOperations.GetRemoteUri().Returns(remoteUri); - gitOperations.GetCurrentBranch().Returns("branch-1"); - gitOperations.GetBranchesThatExistLocally(Arg.Any()).Returns(["branch-1", "branch-2"]); - gitOperations.GetBranchesThatExistInRemote(Arg.Any()).Returns(["branch-1"]); - var stacks = new List( [ - new("Stack1", remoteUri, "branch-1", ["branch-2"]), - new("Stack2", remoteUri, "branch-3", ["branch-4"]) + new("Stack1", repo.RemoteUri, sourceBranch, [branchToCleanup, branchToKeep]), + new("Stack2", repo.RemoteUri, sourceBranch, []) ]); + + var remoteUri = Some.HttpsUri().ToString(); stackConfig.Load().Returns(stacks); inputProvider.Select(Questions.SelectStack, Arg.Any()).Returns("Stack1"); @@ -43,31 +47,33 @@ public async Task WhenBranchExistsLocally_ButNotInRemote_BranchIsDeletedLocally( await handler.Handle(CleanupStackCommandInputs.Empty); // Assert - gitOperations.Received().DeleteLocalBranch("branch-2"); + gitOperations.GetBranchesThatExistLocally([branchToCleanup, branchToKeep]).Should().BeEquivalentTo([branchToKeep]); } [Fact] public async Task WhenBranchExistsLocally_AndInRemote_BranchIsNotDeletedLocally() { // Arrange - var gitOperations = Substitute.For(); - var gitHubOperations = Substitute.For(); + var sourceBranch = Some.BranchName(); + var branchToKeep = Some.BranchName(); + var anotherBranchToKeep = Some.BranchName(); + using var repo = new TestGitRepositoryBuilder() + .WithBranch(sourceBranch, true) + .WithBranch(branchToKeep, true) + .WithBranch(anotherBranchToKeep, true) + .Build(); + var stackConfig = Substitute.For(); var inputProvider = Substitute.For(); var outputProvider = Substitute.For(); + var gitOperations = new GitOperations(outputProvider, repo.GitOperationSettings); + var gitHubOperations = Substitute.For(); var handler = new CleanupStackCommandHandler(inputProvider, outputProvider, gitOperations, gitHubOperations, stackConfig); - var remoteUri = Some.HttpsUri().ToString(); - - gitOperations.GetRemoteUri().Returns(remoteUri); - gitOperations.GetCurrentBranch().Returns("branch-1"); - gitOperations.GetBranchesThatExistLocally(Arg.Any()).Returns(["branch-1", "branch-2"]); - gitOperations.GetBranchesThatExistInRemote(Arg.Any()).Returns(["branch-1", "branch-2"]); - var stacks = new List( [ - new("Stack1", remoteUri, "branch-1", ["branch-2"]), - new("Stack2", remoteUri, "branch-3", ["branch-4"]) + new("Stack1", repo.RemoteUri, sourceBranch, [branchToKeep, anotherBranchToKeep]), + new("Stack2", repo.RemoteUri, sourceBranch, []) ]); stackConfig.Load().Returns(stacks); @@ -78,31 +84,33 @@ public async Task WhenBranchExistsLocally_AndInRemote_BranchIsNotDeletedLocally( await handler.Handle(CleanupStackCommandInputs.Empty); // Assert - gitOperations.DidNotReceive().DeleteLocalBranch("branch-2"); + gitOperations.GetBranchesThatExistLocally([branchToKeep, anotherBranchToKeep]).Should().BeEquivalentTo([branchToKeep, anotherBranchToKeep]); } [Fact] public async Task WhenConfirmationIsFalse_DoesNotDeleteAnyBranches() { // Arrange - var gitOperations = Substitute.For(); - var gitHubOperations = Substitute.For(); + var sourceBranch = Some.BranchName(); + var branchToCleanup = Some.BranchName(); + var branchToKeep = Some.BranchName(); + using var repo = new TestGitRepositoryBuilder() + .WithBranch(sourceBranch, true) + .WithBranch(branchToCleanup, false) + .WithBranch(branchToKeep, true) + .Build(); + var stackConfig = Substitute.For(); var inputProvider = Substitute.For(); var outputProvider = Substitute.For(); + var gitOperations = new GitOperations(outputProvider, repo.GitOperationSettings); + var gitHubOperations = Substitute.For(); var handler = new CleanupStackCommandHandler(inputProvider, outputProvider, gitOperations, gitHubOperations, stackConfig); - var remoteUri = Some.HttpsUri().ToString(); - - gitOperations.GetRemoteUri().Returns(remoteUri); - gitOperations.GetCurrentBranch().Returns("branch-1"); - gitOperations.GetBranchesThatExistLocally(Arg.Any()).Returns(["branch-1", "branch-2"]); - gitOperations.GetBranchesThatExistInRemote(Arg.Any()).Returns(["branch-1"]); - var stacks = new List( [ - new("Stack1", remoteUri, "branch-1", ["branch-2"]), - new("Stack2", remoteUri, "branch-3", ["branch-4"]) + new("Stack1", repo.RemoteUri, sourceBranch, [branchToCleanup, branchToKeep]), + new("Stack2", repo.RemoteUri, sourceBranch, []) ]); stackConfig.Load().Returns(stacks); @@ -113,31 +121,33 @@ public async Task WhenConfirmationIsFalse_DoesNotDeleteAnyBranches() await handler.Handle(CleanupStackCommandInputs.Empty); // Assert - gitOperations.DidNotReceive().DeleteLocalBranch("branch-2"); + gitOperations.GetBranchesThatExistLocally([branchToKeep, branchToCleanup]).Should().BeEquivalentTo([branchToKeep, branchToCleanup]); } [Fact] public async Task WhenStackNameIsProvided_ItIsNotAskedFor() { // Arrange - var gitOperations = Substitute.For(); - var gitHubOperations = Substitute.For(); + var sourceBranch = Some.BranchName(); + var branchToCleanup = Some.BranchName(); + var branchToKeep = Some.BranchName(); + using var repo = new TestGitRepositoryBuilder() + .WithBranch(sourceBranch, true) + .WithBranch(branchToCleanup, false) + .WithBranch(branchToKeep, true) + .Build(); + var stackConfig = Substitute.For(); var inputProvider = Substitute.For(); var outputProvider = Substitute.For(); + var gitOperations = new GitOperations(outputProvider, repo.GitOperationSettings); + var gitHubOperations = Substitute.For(); var handler = new CleanupStackCommandHandler(inputProvider, outputProvider, gitOperations, gitHubOperations, stackConfig); - var remoteUri = Some.HttpsUri().ToString(); - - gitOperations.GetRemoteUri().Returns(remoteUri); - gitOperations.GetCurrentBranch().Returns("branch-1"); - gitOperations.GetBranchesThatExistLocally(Arg.Any()).Returns(["branch-1", "branch-2"]); - gitOperations.GetBranchesThatExistInRemote(Arg.Any()).Returns(["branch-1"]); - var stacks = new List( [ - new("Stack1", remoteUri, "branch-1", ["branch-2"]), - new("Stack2", remoteUri, "branch-3", ["branch-4"]) + new("Stack1", repo.RemoteUri, sourceBranch, [branchToCleanup, branchToKeep]), + new("Stack2", repo.RemoteUri, sourceBranch, []) ]); stackConfig.Load().Returns(stacks); @@ -154,24 +164,26 @@ public async Task WhenStackNameIsProvided_ItIsNotAskedFor() public async Task WhenForceIsProvided_ItIsNotAskedFor() { // Arrange - var gitOperations = Substitute.For(); - var gitHubOperations = Substitute.For(); + var sourceBranch = Some.BranchName(); + var branchToCleanup = Some.BranchName(); + var branchToKeep = Some.BranchName(); + using var repo = new TestGitRepositoryBuilder() + .WithBranch(sourceBranch, true) + .WithBranch(branchToCleanup, false) + .WithBranch(branchToKeep, true) + .Build(); + var stackConfig = Substitute.For(); var inputProvider = Substitute.For(); var outputProvider = Substitute.For(); + var gitOperations = new GitOperations(outputProvider, repo.GitOperationSettings); + var gitHubOperations = Substitute.For(); var handler = new CleanupStackCommandHandler(inputProvider, outputProvider, gitOperations, gitHubOperations, stackConfig); - var remoteUri = Some.HttpsUri().ToString(); - - gitOperations.GetRemoteUri().Returns(remoteUri); - gitOperations.GetCurrentBranch().Returns("branch-1"); - gitOperations.GetBranchesThatExistLocally(Arg.Any()).Returns(["branch-1", "branch-2"]); - gitOperations.GetBranchesThatExistInRemote(Arg.Any()).Returns(["branch-1"]); - var stacks = new List( [ - new("Stack1", remoteUri, "branch-1", ["branch-2"]), - new("Stack2", remoteUri, "branch-3", ["branch-4"]) + new("Stack1", repo.RemoteUri, sourceBranch, [branchToCleanup, branchToKeep]), + new("Stack2", repo.RemoteUri, sourceBranch, []) ]); stackConfig.Load().Returns(stacks); @@ -188,24 +200,26 @@ public async Task WhenForceIsProvided_ItIsNotAskedFor() public async Task WhenStackNameIsProvided_ButStackDoesNotExist_Throws() { // Arrange - var gitOperations = Substitute.For(); - var gitHubOperations = Substitute.For(); + var sourceBranch = Some.BranchName(); + var branchToCleanup = Some.BranchName(); + var branchToKeep = Some.BranchName(); + using var repo = new TestGitRepositoryBuilder() + .WithBranch(sourceBranch, true) + .WithBranch(branchToCleanup, false) + .WithBranch(branchToKeep, true) + .Build(); + var stackConfig = Substitute.For(); var inputProvider = Substitute.For(); var outputProvider = Substitute.For(); + var gitOperations = new GitOperations(outputProvider, repo.GitOperationSettings); + var gitHubOperations = Substitute.For(); var handler = new CleanupStackCommandHandler(inputProvider, outputProvider, gitOperations, gitHubOperations, stackConfig); - var remoteUri = Some.HttpsUri().ToString(); - - gitOperations.GetRemoteUri().Returns(remoteUri); - gitOperations.GetCurrentBranch().Returns("branch-1"); - gitOperations.GetBranchesThatExistLocally(Arg.Any()).Returns(["branch-1", "branch-2"]); - gitOperations.GetBranchesThatExistInRemote(Arg.Any()).Returns(["branch-1"]); - var stacks = new List( [ - new("Stack1", remoteUri, "branch-1", ["branch-2"]), - new("Stack2", remoteUri, "branch-3", ["branch-4"]) + new("Stack1", repo.RemoteUri, sourceBranch, [branchToCleanup, branchToKeep]), + new("Stack2", repo.RemoteUri, sourceBranch, []) ]); stackConfig.Load().Returns(stacks); @@ -223,23 +237,25 @@ await handler.Invoking(async h => await h.Handle(new CleanupStackCommandInputs(i public async Task WhenOnlyASingleStackExists_StackIsSelectedAutomatically() { // Arrange - var gitOperations = Substitute.For(); - var gitHubOperations = Substitute.For(); + var sourceBranch = Some.BranchName(); + var branchToCleanup = Some.BranchName(); + var branchToKeep = Some.BranchName(); + using var repo = new TestGitRepositoryBuilder() + .WithBranch(sourceBranch, true) + .WithBranch(branchToCleanup, false) + .WithBranch(branchToKeep, true) + .Build(); + var stackConfig = Substitute.For(); var inputProvider = Substitute.For(); var outputProvider = Substitute.For(); + var gitOperations = new GitOperations(outputProvider, repo.GitOperationSettings); + var gitHubOperations = Substitute.For(); var handler = new CleanupStackCommandHandler(inputProvider, outputProvider, gitOperations, gitHubOperations, stackConfig); - var remoteUri = Some.HttpsUri().ToString(); - - gitOperations.GetRemoteUri().Returns(remoteUri); - gitOperations.GetCurrentBranch().Returns("branch-1"); - gitOperations.GetBranchesThatExistLocally(Arg.Any()).Returns(["branch-1", "branch-2"]); - gitOperations.GetBranchesThatExistInRemote(Arg.Any()).Returns(["branch-1"]); - var stacks = new List( [ - new("Stack1", remoteUri, "branch-1", ["branch-2"]) + new("Stack1", repo.RemoteUri, sourceBranch, [branchToCleanup, branchToKeep]), ]); stackConfig.Load().Returns(stacks); diff --git a/src/Stack.Tests/Helpers/TestGitRepositoryBuilder.cs b/src/Stack.Tests/Helpers/TestGitRepositoryBuilder.cs index 7e420b1..cf5e083 100644 --- a/src/Stack.Tests/Helpers/TestGitRepositoryBuilder.cs +++ b/src/Stack.Tests/Helpers/TestGitRepositoryBuilder.cs @@ -7,11 +7,17 @@ namespace Stack.Tests.Helpers; public class TestGitRepositoryBuilder { - List branches = []; + List<(string Name, bool PushToRemote)> branches = []; public TestGitRepositoryBuilder WithBranch(string branch) { - branches.Add(branch); + branches.Add((branch, false)); + return this; + } + + public TestGitRepositoryBuilder WithBranch(string branch, bool pushToRemote) + { + branches.Add((branch, pushToRemote)); return this; } @@ -21,7 +27,7 @@ public TestGitRepository Build() var remoteDirectory = new TemporaryDirectory(remote); var localDirectory = TemporaryDirectory.Create(); - Repository.Init(remoteDirectory.DirectoryPath, true); + var remoteRepo = new Repository(Repository.Init(remoteDirectory.DirectoryPath, true)); var repo = new Repository(Repository.Clone(remote, localDirectory.DirectoryPath)); var defaultBranch = Some.BranchName(); repo.Refs.UpdateTarget("HEAD", "refs/heads/" + defaultBranch); @@ -30,7 +36,15 @@ public TestGitRepository Build() foreach (var branch in branches) { - repo.CreateBranch(branch); + var newBranch = repo.CreateBranch(branch.Name); + + if (branch.PushToRemote) + { + repo.Branches.Update(newBranch, + b => b.Remote = repo.Network.Remotes["origin"].Name, + b => b.UpstreamBranch = newBranch.CanonicalName); + repo.Network.Push(newBranch); + } } return new TestGitRepository(localDirectory, remoteDirectory, repo);