Skip to content

Commit

Permalink
Solution items should respect folders option (#495)
Browse files Browse the repository at this point in the history
  • Loading branch information
ptasev authored Jul 3, 2023
1 parent 68bc136 commit 77d4df6
Show file tree
Hide file tree
Showing 5 changed files with 322 additions and 52 deletions.
114 changes: 114 additions & 0 deletions src/Microsoft.VisualStudio.SlnGen.UnitTests/SlnFileTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,7 @@ public void ProjectSolutionFolders()
string projectName2 = Path.GetFileName(Path.GetTempFileName());
string projectName3 = Path.GetFileName(Path.GetTempFileName());
string projectName4 = Path.GetFileName(Path.GetTempFileName());
string solutionItem1Name = Path.GetFileName(Path.GetTempFileName());
Project[] projects =
{
new Project
Expand All @@ -627,11 +628,14 @@ public void ProjectSolutionFolders()
projects[1].SetProperty(MSBuildPropertyNames.SlnGenSolutionFolder, "FolderB");
projects[2].SetProperty(MSBuildPropertyNames.SlnGenSolutionFolder, "FolderB");

string[] solutionItems = new[] { Path.Combine(root, "SubFolder1", solutionItem1Name) };

string solutionFilePath = GetTempFileName();

SlnFile slnFile = new SlnFile();

slnFile.AddProjects(projects, new Dictionary<string, Guid>(), projects[1].FullPath);
slnFile.AddSolutionItems(solutionItems);
slnFile.Save(solutionFilePath, useFolders: false);

SolutionFile s = SolutionFile.Parse(solutionFilePath);
Expand All @@ -642,13 +646,19 @@ public void ProjectSolutionFolders()
ProjectInSolution project4 = s.ProjectsByGuid.FirstOrDefault(i => i.Value.ProjectName.Equals(Path.GetFileNameWithoutExtension(projectName4))).Value;
ProjectInSolution folderA = s.ProjectsByGuid.FirstOrDefault(i => i.Value.ProjectName.Equals("FolderA")).Value;
ProjectInSolution folderB = s.ProjectsByGuid.FirstOrDefault(i => i.Value.ProjectName.Equals("FolderB")).Value;
ProjectInSolution folderSolutionItems = s.ProjectsInOrder.FirstOrDefault(i => i.ProjectName.Equals("Solution Items"));

project1.ParentProjectGuid.ShouldBe(folderA.ProjectGuid);
project2.ParentProjectGuid.ShouldBe(folderB.ProjectGuid);
project3.ParentProjectGuid.ShouldBe(folderB.ProjectGuid);
project4.ParentProjectGuid.ShouldBeNull();
folderA.ProjectType.ShouldBe(SolutionProjectType.SolutionFolder);
folderB.ProjectType.ShouldBe(SolutionProjectType.SolutionFolder);

folderSolutionItems.ShouldNotBeNull();
folderSolutionItems.ProjectType.ShouldBe(SolutionProjectType.SolutionFolder);
folderSolutionItems.ProjectName.ShouldBe("Solution Items");
folderSolutionItems.ParentProjectGuid.ShouldBeNull();
}

[Fact]
Expand Down Expand Up @@ -856,6 +866,7 @@ public void WithFoldersDoNotIgnoreMainProject()
string projectName1 = Path.GetFileName(Path.GetTempFileName());
string projectName2 = Path.GetFileName(Path.GetTempFileName());
string projectName3 = Path.GetFileName(Path.GetTempFileName());
string solutionItem1Name = Path.GetFileName(Path.GetTempFileName());
Project[] projects =
{
new Project
Expand All @@ -872,15 +883,23 @@ public void WithFoldersDoNotIgnoreMainProject()
},
};

string[] solutionItems = new[] { Path.Combine(root, "SubFolder3", solutionItem1Name) };

string solutionFilePath = GetTempFileName();

SlnFile slnFile = new SlnFile();

slnFile.AddProjects(projects, new Dictionary<string, Guid>(), projects[1].FullPath);
slnFile.AddSolutionItems(solutionItems);
slnFile.Save(solutionFilePath, true);

SolutionFile solutionFile = SolutionFile.Parse(solutionFilePath);

ProjectInSolution folderSubFolder3 = solutionFile.ProjectsInOrder.FirstOrDefault(i => i.ProjectName.Equals("SubFolder3"));
folderSubFolder3.ShouldNotBeNull();
folderSubFolder3.ProjectType.ShouldBe(SolutionProjectType.SolutionFolder);
folderSubFolder3.ParentProjectGuid.ShouldBeNull();

foreach (ProjectInSolution slnProject in solutionFile.ProjectsInOrder)
{
if (slnProject.ProjectName == projectName1)
Expand All @@ -905,6 +924,7 @@ public void WithFoldersIgnoreMainProject()
string projectName1 = Path.GetFileName(Path.GetTempFileName());
string projectName2 = Path.GetFileName(Path.GetTempFileName());
string projectName3 = Path.GetFileName(Path.GetTempFileName());
string solutionItem1Name = Path.GetFileName(Path.GetTempFileName());
Project[] projects =
{
new Project
Expand All @@ -921,15 +941,23 @@ public void WithFoldersIgnoreMainProject()
},
};

string[] solutionItems = new[] { Path.Combine(root, "SubFolder3", solutionItem1Name) };

string solutionFilePath = GetTempFileName();

SlnFile slnFile = new SlnFile();

slnFile.AddProjects(projects, new Dictionary<string, Guid>());
slnFile.AddSolutionItems(solutionItems);
slnFile.Save(solutionFilePath, true);

SolutionFile solutionFile = SolutionFile.Parse(solutionFilePath);

ProjectInSolution folderSubFolder3 = solutionFile.ProjectsInOrder.FirstOrDefault(i => i.ProjectName.Equals("SubFolder3"));
folderSubFolder3.ShouldNotBeNull();
folderSubFolder3.ProjectType.ShouldBe(SolutionProjectType.SolutionFolder);
folderSubFolder3.ParentProjectGuid.ShouldBeNull();

foreach (ProjectInSolution slnProject in solutionFile.ProjectsInOrder)
{
if (slnProject.ProjectName == projectName1)
Expand All @@ -947,6 +975,92 @@ public void WithFoldersIgnoreMainProject()
}
}

[Theory]
[InlineData(false, false)]
[InlineData(false, true)]
[InlineData(true, false)]
[InlineData(true, true)]
public void WithFoldersDoesNotCreateRootFolder(bool ignoreMainProject, bool collapseFolders)
{
string root = Path.GetTempPath();
string projectName1 = Path.GetFileName(Path.GetTempFileName());
string projectName2 = Path.GetFileName(Path.GetTempFileName());
string projectName3 = Path.GetFileName(Path.GetTempFileName());
string projectName4 = Path.GetFileName(Path.GetTempFileName());
string solutionItem1Name = Path.GetFileName(Path.GetTempFileName());
Project[] projects =
{
new Project
{
FullPath = Path.Combine(root, "SubFolder1", "Project1", projectName1),
},
new Project
{
FullPath = Path.Combine(root, "SubFolder1", "Project2", projectName2),
},
new Project
{
FullPath = Path.Combine(root, "SubFolder2", "Project3", projectName3),
},
new Project
{
FullPath = Path.Combine(root, "SubFolder2", "Project4", projectName4),
},
};

string[] solutionItems = new[] { Path.Combine(root, "SubFolder3", solutionItem1Name) };

string solutionFilePath = GetTempFileName();

SlnFile slnFile = new SlnFile();

slnFile.AddProjects(projects, new Dictionary<string, Guid>(), ignoreMainProject ? null : projects[1].FullPath);
slnFile.AddSolutionItems(solutionItems);
slnFile.Save(solutionFilePath, useFolders: true, collapseFolders: collapseFolders);

SolutionFile solutionFile = SolutionFile.Parse(solutionFilePath);

ProjectInSolution folderSubFolder3 = solutionFile.ProjectsInOrder.FirstOrDefault(i => i.ProjectName.Equals("SubFolder3"));
folderSubFolder3.ShouldNotBeNull();
folderSubFolder3.ProjectType.ShouldBe(SolutionProjectType.SolutionFolder);
folderSubFolder3.ParentProjectGuid.ShouldBeNull();

foreach (ProjectInSolution slnProject in solutionFile.ProjectsInOrder)
{
if (slnProject.ProjectName == projectName1)
{
if (ignoreMainProject)
{
slnProject.ParentProjectGuid.ShouldNotBeNull();
}
else
{
slnProject.ParentProjectGuid.ShouldBeNull();
}
}
else if (slnProject.ProjectName == projectName2)
{
slnProject.ParentProjectGuid.ShouldNotBeNull();
}
else if (slnProject.ProjectName == projectName3)
{
slnProject.ParentProjectGuid.ShouldNotBeNull();
}
else if (slnProject.ProjectName == projectName4)
{
slnProject.ParentProjectGuid.ShouldNotBeNull();
}
else if (slnProject.ProjectName == "SubFolder1")
{
slnProject.ParentProjectGuid.ShouldBeNull();
}
else if (slnProject.ProjectName == "SubFolder2")
{
slnProject.ParentProjectGuid.ShouldBeNull();
}
}
}

[Fact]
public void VisualStudioVersionIsWritten()
{
Expand Down
61 changes: 52 additions & 9 deletions src/Microsoft.VisualStudio.SlnGen.UnitTests/SlnHierarchyTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,13 @@ public void HierarchyIgnoresCase()
},
};

SlnHierarchy hierarchy = SlnHierarchy.CreateFromProjectDirectories(projects);
IReadOnlyCollection<string> solutionItems = new[]
{
Path.Combine(_driveRoot, "Code", "A.txt"),
Path.Combine(_driveRoot, "code", "A.txt"),
};

SlnHierarchy hierarchy = SlnHierarchy.CreateFromProjectDirectories(projects, solutionItems);

GetFolderStructureAsString(hierarchy.Folders).ShouldBe(
$@"{_driveRoot}Code - Code
Expand Down Expand Up @@ -80,10 +86,17 @@ public void HierarchyIsCorrectlyFormed()
},
};

SlnHierarchy hierarchy = SlnHierarchy.CreateFromProjectDirectories(projects);
IReadOnlyCollection<string> solutionItems = new[]
{
Path.Combine(_driveRoot, "zoo", "A.txt"),
Path.Combine(_driveRoot, "zoo", "foo", "bar", "B.txt"),
};

SlnHierarchy hierarchy = SlnHierarchy.CreateFromProjectDirectories(projects, solutionItems);

GetFolderStructureAsString(hierarchy.Folders).ShouldBe(
$@"{_driveRoot}zoo{Path.DirectorySeparatorChar}foo - foo
$@"{_driveRoot}zoo - zoo
{_driveRoot}zoo{Path.DirectorySeparatorChar}foo - foo
{_driveRoot}zoo{Path.DirectorySeparatorChar}foo{Path.DirectorySeparatorChar}bar - bar
{_driveRoot}zoo{Path.DirectorySeparatorChar}foo{Path.DirectorySeparatorChar}bar{Path.DirectorySeparatorChar}baz - baz
{_driveRoot}zoo{Path.DirectorySeparatorChar}foo{Path.DirectorySeparatorChar}bar{Path.DirectorySeparatorChar}baz1 - baz1
Expand Down Expand Up @@ -127,7 +140,12 @@ public void SingleFolderWithProjectsShouldNotCollapseIntoParentFolderWithProject
},
};

SlnHierarchy hierarchy = SlnHierarchy.CreateFromProjectDirectories(projects, collapseFolders: true);
IReadOnlyCollection<string> solutionItems = new[]
{
Path.Combine(_driveRoot, "foo", "project3", "B.txt"),
};

SlnHierarchy hierarchy = SlnHierarchy.CreateFromProjectDirectories(projects, solutionItems, collapseFolders: true);

GetFolderStructureAsString(hierarchy.Folders).ShouldBe(
$@"{_driveRoot}foo - foo
Expand Down Expand Up @@ -164,7 +182,14 @@ public void HierarchyWithMultipleSubfoldersUnderACollapsedFolderIsCorrectlyForme
},
};

SlnHierarchy hierarchy = SlnHierarchy.CreateFromProjectDirectories(projects, collapseFolders: true);
IReadOnlyCollection<string> solutionItems = new[]
{
Path.Combine(_driveRoot, "foo", "src", "subfolder", "src", "A.txt"),
Path.Combine(_driveRoot, "foo", "project2", "B.txt"),
Path.Combine(_driveRoot, "foo", "C.txt"),
};

SlnHierarchy hierarchy = SlnHierarchy.CreateFromProjectDirectories(projects, solutionItems, collapseFolders: true);

GetFolderStructureAsString(hierarchy.Folders).ShouldBe(
$@"{_driveRoot}foo - foo
Expand Down Expand Up @@ -209,12 +234,20 @@ public void HierarchyWithCollapsedFoldersIsCorrectlyFormed()
},
};

SlnHierarchy hierarchy = SlnHierarchy.CreateFromProjectDirectories(projects, collapseFolders: true);
IReadOnlyList<string> solutionItems = new[]
{
Path.Combine(_driveRoot, "zoo", "foo", "bar", "qux", "A.txt"),
Path.Combine(_driveRoot, "zoo", "foo", "foo1", "B.txt"),
Path.Combine(_driveRoot, "zoo", "foo", "foo1", "foo2", "baz3", "C.txt"),
};

SlnHierarchy hierarchy = SlnHierarchy.CreateFromProjectDirectories(projects, solutionItems, collapseFolders: true);

GetFolderStructureAsString(hierarchy.Folders).ShouldBe(
$@"{_driveRoot}zoo{Path.DirectorySeparatorChar}foo - foo
{_driveRoot}zoo{Path.DirectorySeparatorChar}foo{Path.DirectorySeparatorChar}bar - bar {SlnHierarchy.Separator} qux
{_driveRoot}zoo{Path.DirectorySeparatorChar}foo{Path.DirectorySeparatorChar}foo1 - foo1 {SlnHierarchy.Separator} foo2",
{_driveRoot}zoo{Path.DirectorySeparatorChar}foo{Path.DirectorySeparatorChar}foo1 - foo1
{_driveRoot}zoo{Path.DirectorySeparatorChar}foo{Path.DirectorySeparatorChar}foo1{Path.DirectorySeparatorChar}foo2 - foo2",
StringCompareShould.IgnoreLineEndings);
}

Expand All @@ -241,15 +274,25 @@ public void SlnGenSolutionFolderNestedHierarchy()
},
};

SlnHierarchy hierarchy = SlnHierarchy.CreateFromProjectSolutionFolder(projects);
IReadOnlyList<string> solutionItems = new[]
{
Path.Combine(_driveRoot, "zoo", "foo2", "A.txt"),
Path.Combine(_driveRoot, "zoo", "B.txt"),
};

SlnHierarchy hierarchy = SlnHierarchy.CreateFromProjectSolutionFolder(projects, solutionItems);

GetFolderStructureAsString(hierarchy.Folders).ShouldBe(
$@"zoo - zoo
$@" -
zoo - zoo
zoo{Path.DirectorySeparatorChar}foo - foo
zoo{Path.DirectorySeparatorChar}foo{Path.DirectorySeparatorChar}bar - bar
zoo{Path.DirectorySeparatorChar}foo{Path.DirectorySeparatorChar}bar{Path.DirectorySeparatorChar}baz - baz
zoo{Path.DirectorySeparatorChar}foo{Path.DirectorySeparatorChar}bar{Path.DirectorySeparatorChar}baz1 - baz1",
StringCompareShould.IgnoreLineEndings);

hierarchy.RootFolder.SolutionItems[0].ShouldBe(solutionItems[0]);
hierarchy.RootFolder.SolutionItems[1].ShouldBe(solutionItems[1]);
}

private static string GetFolderStructureAsString(IEnumerable<SlnFolder> folders)
Expand Down
Loading

0 comments on commit 77d4df6

Please sign in to comment.