Skip to content

Commit

Permalink
Correct tests for SubmoduleStatusProvider
Browse files Browse the repository at this point in the history
  • Loading branch information
gerhardol committed May 17, 2020
1 parent 28e2563 commit 5e7df72
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 43 deletions.
3 changes: 1 addition & 2 deletions GitCommands/Submodules/SubmoduleInfoResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ public class SubmoduleInfoResult
public IList<SubmoduleInfo> OurSubmodules { get; } = new List<SubmoduleInfo>();

// List of SubmoduleInfo for all submodules under TopProject.
// Only populated if current module is a submodule (i.e. is not TopProject)
public IList<SubmoduleInfo> SuperSubmodules { get; } = new List<SubmoduleInfo>();
public IList<SubmoduleInfo> AllSubmodules { get; } = new List<SubmoduleInfo>();

// Always set to the top-most module.
[NotNull]
Expand Down
61 changes: 40 additions & 21 deletions GitCommands/Submodules/SubmoduleStatusProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,12 @@ public async Task UpdateSubmodulesStructureAsync(string workingDirectory, string
var result = new SubmoduleInfoResult { Module = currentModule };

// Add all submodules inside the current repository:
GetRepositorySubmodulesStructure(result, noBranchText);
GetSuperProjectRepositorySubmodulesStructure(currentModule, result, noBranchText);
SetOurSubmoduleData(currentModule, result);

// Prepare info for status updates
_submoduleInfos[result.TopProject.Path] = result.TopProject;
var allSubmodules = result.SuperProject == null ? result.OurSubmodules : result.SuperSubmodules;
foreach (var info in allSubmodules)
foreach (var info in result.AllSubmodules)
{
_submoduleInfos[info.Path] = info;
}
Expand Down Expand Up @@ -170,7 +169,7 @@ private void GetRepositorySubmodulesStructure(SubmoduleInfoResult result, string
}

var smi = new SubmoduleInfo { Text = name, Path = path };
result.OurSubmodules.Add(smi);
result.AllSubmodules.Add(smi);
}
}

Expand All @@ -185,6 +184,7 @@ private void GetSuperProjectRepositorySubmodulesStructure(GitModule currentModul
if (isCurrentTopProject)
{
SetTopProjectSubmoduleInfo(result, noBranchText, result.Module, false, isCurrentTopProject);
GetRepositorySubmodulesStructure(result, noBranchText);

return;
}
Expand All @@ -199,7 +199,7 @@ private void GetSuperProjectRepositorySubmodulesStructure(GitModule currentModul
// Set result.TopProject
SetTopProjectSubmoduleInfo(result, noBranchText, topProject, isParentTopProject, isCurrentTopProject);

// Set result.CurrentSubmoduleName and populate result.SuperSubmodules
// Set result.CurrentSubmoduleName and populate result.AllSubmodules
SetSubmoduleData(currentModule, result, noBranchText, topProject);
}

Expand Down Expand Up @@ -247,26 +247,45 @@ private void SetSuperProjectSubmoduleInfo(GitModule superprojectModule, Submodul
private void SetSubmoduleData(GitModule currentModule, SubmoduleInfoResult result, string noBranchText, IGitModule topProject)
{
var submodules = topProject.GetSubmodulesLocalPaths().OrderBy(submoduleName => submoduleName).ToArray();
if (submodules.Any())
if (!submodules.Any())
{
string localPath = result.Module.WorkingDir.Substring(topProject.WorkingDir.Length);
localPath = Path.GetDirectoryName(localPath).ToPosixPath();
return;
}

string localPath = result.Module.WorkingDir.Substring(topProject.WorkingDir.Length);
localPath = Path.GetDirectoryName(localPath).ToPosixPath();

foreach (var submodule in submodules)
{
string path = topProject.GetSubmoduleFullPath(submodule);
string name = submodule + GetBranchNameSuffix(path, noBranchText);

bool bold = false;
if (submodule == localPath)
{
result.CurrentSubmoduleName = currentModule.GetCurrentSubmoduleLocalPath();
bold = true;
}

var smi = new SubmoduleInfo { Text = name, Path = path, Bold = bold };
result.AllSubmodules.Add(smi);
}
}

foreach (var submodule in submodules)
private void SetOurSubmoduleData(GitModule currentModule, SubmoduleInfoResult result)
{
foreach (var submodule in currentModule.GetSubmodulesLocalPaths())
{
string path = currentModule.GetSubmoduleFullPath(submodule);
var smi = result.AllSubmodules.FirstOrDefault(i => i.Path == path);
if (smi != null)
{
string path = topProject.GetSubmoduleFullPath(submodule);
string name = submodule + GetBranchNameSuffix(path, noBranchText);

bool bold = false;
if (submodule == localPath)
{
result.CurrentSubmoduleName = currentModule.GetCurrentSubmoduleLocalPath();
bold = true;
}

var smi = new SubmoduleInfo { Text = name, Path = path, Bold = bold };
result.SuperSubmodules.Add(smi);
// Just ignore the unexpected situation that smi is not already added
result.OurSubmodules.Add(smi);
}

var module = new GitModule(path);
SetOurSubmoduleData(module, result);
}
}

Expand Down
15 changes: 3 additions & 12 deletions GitUI/BranchTreePanel/RepoObjectsTree.Nodes.Submodules.cs
Original file line number Diff line number Diff line change
Expand Up @@ -262,17 +262,8 @@ private Nodes FillSubmoduleTree(SubmoduleInfoResult result)

var submoduleNodes = new List<SubmoduleNode>();

// We always want to display submodules rooted from the top project. If the currently open project is the top project,
// OurSubmodules contains all child submodules recursively; otherwise, if we're currently in a submodule, SuperSubmodules
// contains all submodule info relative to the top project.
if (result.SuperSubmodules?.Count > 0)
{
CreateSubmoduleNodes(result.SuperSubmodules, threadModule, ref submoduleNodes);
}
else
{
CreateSubmoduleNodes(result.OurSubmodules, threadModule, ref submoduleNodes);
}
// We always want to display submodules rooted from the top project.
CreateSubmoduleNodes(result.AllSubmodules, threadModule, ref submoduleNodes);

var nodes = new Nodes(this);
AddNodesToTree(ref nodes, submoduleNodes, threadModule, result.TopProject);
Expand All @@ -281,7 +272,7 @@ private Nodes FillSubmoduleTree(SubmoduleInfoResult result)

private void CreateSubmoduleNodes(IEnumerable<SubmoduleInfo> submodules, GitModule threadModule, ref List<SubmoduleNode> nodes)
{
// result.OurSubmodules/SuperSubmodules contain a recursive list of submodules, but don't provide info about the super
// result.OurSubmodules/AllSubmodules contain a recursive list of submodules, but don't provide info about the super
// project path. So we deduce these by substring matching paths against an ordered list of all paths.
var modulePaths = submodules.Select(info => info.Path).ToList();

Expand Down
2 changes: 1 addition & 1 deletion GitUI/CommandsDialogs/FormBrowse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2642,7 +2642,7 @@ private async Task PopulateToolbarAsync(SubmoduleInfoResult result, Cancellation
}

newItems.Add(CreateSubmoduleMenuItem(cancelToken, result.SuperProject, _superprojectModuleFormat.Text));
newItems.AddRange(result.SuperSubmodules.Select(submodule => CreateSubmoduleMenuItem(cancelToken, submodule)));
newItems.AddRange(result.AllSubmodules.Select(submodule => CreateSubmoduleMenuItem(cancelToken, submodule)));
toolStripButtonLevelUp.ToolTipText = _goToSuperProject.Text;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public async Task UpdateSubmoduleStructure_valid_result_for_top_module()
result.SuperProject.Should().Be(null);
result.CurrentSubmoduleName.Should().Be(null);
result.OurSubmodules.Select(info => info.Path).Should().Contain(_repo2Module.WorkingDir, _repo3Module.WorkingDir);
result.SuperSubmodules.Should().BeEmpty();
result.AllSubmodules.Count().Should().Be(2);
result.OurSubmodules.All(i => i.Detailed == null).Should().BeTrue();
}

Expand All @@ -82,7 +82,7 @@ public async Task UpdateSubmoduleStructure_valid_result_for_first_nested_submodu
result.SuperProject.Should().Be(result.TopProject);
result.CurrentSubmoduleName.Should().Be("repo2");
result.OurSubmodules.Select(info => info.Path).Should().ContainSingle(_repo3Module.WorkingDir);
result.SuperSubmodules.Select(info => info.Path).Should().Contain(_repo2Module.WorkingDir, _repo3Module.WorkingDir);
result.AllSubmodules.Select(info => info.Path).Should().Contain(_repo2Module.WorkingDir, _repo3Module.WorkingDir);
result.OurSubmodules.All(i => i.Detailed == null).Should().BeTrue();
}

Expand All @@ -96,7 +96,7 @@ public async Task UpdateSubmoduleStructure_valid_result_for_second_nested_submod
result.SuperProject.Path.Should().Be(_repo2Module.WorkingDir);
result.CurrentSubmoduleName.Should().Be("repo3");
result.OurSubmodules.Select(info => info.Path).Should().BeEmpty();
result.SuperSubmodules.Select(info => info.Path).Should().Contain(_repo2Module.WorkingDir, _repo3Module.WorkingDir);
result.AllSubmodules.Select(info => info.Path).Should().Contain(_repo2Module.WorkingDir, _repo3Module.WorkingDir);
result.OurSubmodules.All(i => i.Detailed == null).Should().BeTrue();
}

Expand Down Expand Up @@ -143,7 +143,8 @@ public async Task Submodule_status_changes_for_first_nested_module()
var changedFiles = GetStatusChangedFiles(currentModule);
changedFiles.Should().HaveCount(0);
await SubmoduleTestHelpers.UpdateSubmoduleStatusAndWaitForResultAsync(_provider, currentModule, changedFiles);
result.OurSubmodules.All(i => i.Detailed == null).Should().BeTrue();
result.AllSubmodules.All(i => i.Detailed == null).Should().BeTrue();
result.TopProject.Detailed.Should().BeNull();

// Make a change in repo1
_repo1.CreateFile(_repo1Module.WorkingDir, "test.txt", "test");
Expand All @@ -164,16 +165,20 @@ public async Task Submodule_status_changes_for_first_nested_module()
changedFiles = GetStatusChangedFiles(currentModule);
changedFiles.Should().HaveCount(1);
await SubmoduleTestHelpers.UpdateSubmoduleStatusAndWaitForResultAsync(_provider, currentModule, changedFiles);

// Fails, for same reason as previous test
////result.OurSubmodules[0].Detailed.IsDirty.Should().BeTrue();
result.OurSubmodules[0].Detailed.IsDirty.Should().BeTrue();
result.AllSubmodules[0].Detailed.IsDirty.Should().BeTrue();
result.AllSubmodules[1].Detailed.IsDirty.Should().BeTrue();
result.TopProject.Detailed.IsDirty.Should().BeTrue();

// Revert the change
File.Delete(Path.Combine(_repo3Module.WorkingDir, "test.txt"));
changedFiles = GetStatusChangedFiles(currentModule);
changedFiles.Should().HaveCount(0);
await SubmoduleTestHelpers.UpdateSubmoduleStatusAndWaitForResultAsync(_provider, currentModule, changedFiles);
result.OurSubmodules.All(i => i.Detailed == null).Should().BeTrue();

// TopProject is unchanged (until refresh)
result.TopProject.Detailed.IsDirty.Should().BeTrue();
}

private static IReadOnlyList<GitItemStatus> GetStatusChangedFiles(IGitModule module)
Expand Down

0 comments on commit 5e7df72

Please sign in to comment.