Skip to content

Commit 2adc9fa

Browse files
Add some unit tests
1 parent 12922ff commit 2adc9fa

File tree

4 files changed

+115
-39
lines changed

4 files changed

+115
-39
lines changed

CodeConverter/Shared/SolutionConverter.cs

Lines changed: 2 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -86,27 +86,8 @@ private IEnumerable<ConversionResult> UpdateProjectReferences(IEnumerable<Projec
8686
}).Where(c => !c.IsIdentity);
8787
}
8888

89-
private static List<(string Find, string Replace, bool FirstOnly)> GetProjectReferenceReplacements(IReadOnlyCollection<Project> projectsToConvert,
90-
string sourceSolutionContents)
91-
{
92-
var projectReferenceReplacements = new List<(string Find, string Replace, bool FirstOnly)>();
93-
foreach (var project in projectsToConvert) {
94-
var projFilename = Path.GetFileName(project.FilePath);
95-
var projDirPath = project.GetDirectoryPath();
96-
97-
var newProjFilename = PathConverter.TogglePathExtension(projFilename);
98-
99-
var projPath = PathConverter.GetFileDirPath(projFilename, projDirPath);
100-
var newProjPath = PathConverter.GetFileDirPath(newProjFilename, projDirPath);
101-
102-
var projPathEscaped = Regex.Escape(projPath);
103-
104-
projectReferenceReplacements.Add((projPathEscaped, newProjPath, false));
105-
if (!string.IsNullOrWhiteSpace(sourceSolutionContents)) projectReferenceReplacements.Add(GetProjectGuidReplacement(projPathEscaped, sourceSolutionContents));
106-
}
107-
108-
return projectReferenceReplacements;
109-
}
89+
private static List<(string Find, string Replace, bool FirstOnly)> GetProjectReferenceReplacements(IReadOnlyCollection<Project> projectsToConvert, string sourceSolutionContents) =>
90+
SolutionFileTextEditor.GetProjectReferenceReplacements(projectsToConvert.Select(p => (FilePath: p.FilePath, DirectoryPath: p.GetDirectoryPath())), sourceSolutionContents).ToList();
11091

11192
private ConversionResult ConvertSolutionFile()
11293
{
@@ -120,26 +101,9 @@ private ConversionResult ConvertSolutionFile()
120101
};
121102
}
122103

123-
private static (string Find, string Replace, bool FirstOnly) GetProjectGuidReplacement(string projPath, string contents)
124-
{
125-
var projGuidRegex = new Regex(projPath + @""", ""({[0-9A-Fa-f\-]{32,36}})("")");
126-
var projGuidMatch = projGuidRegex.Match(contents);
127-
var oldGuid = projGuidMatch.Groups[1].Value;
128-
var newGuid = GetDeterministicGuidFrom(new Guid(oldGuid));
129-
return (oldGuid, newGuid.ToString("B").ToUpperInvariant(), false);
130-
}
131-
132104
private IEnumerable<(string, string, bool)> GetProjectTypeReplacement(Project project, IReadOnlyCollection<(string, string)> typeGuidMappings)
133105
{
134106
return typeGuidMappings.Select(guidReplacement => ($@"Project\s*\(\s*""{guidReplacement.Item1}""\s*\)\s*=\s*""{project.Name}""", $@"Project(""{guidReplacement.Item2}"") = ""{project.Name}""", false));
135107
}
136-
137-
private static Guid GetDeterministicGuidFrom(Guid guidToConvert)
138-
{
139-
var codeConverterStaticGuid = new Guid("{B224816B-CC58-4FF1-8258-CA7E629734A0}");
140-
var deterministicNewBytes = codeConverterStaticGuid.ToByteArray().Zip(guidToConvert.ToByteArray(),
141-
(fromFirst, fromSecond) => (byte)(fromFirst ^ fromSecond));
142-
return new Guid(deterministicNewBytes.ToArray());
143-
}
144108
}
145109
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Text.RegularExpressions;
6+
7+
namespace ICSharpCode.CodeConverter.Shared
8+
{
9+
public class SolutionFileTextEditor
10+
{
11+
public static IEnumerable<(string Find, string Replace, bool FirstOnly)> GetProjectReferenceReplacements(IEnumerable<(string FilePath, string DirectoryPath)> projectsToConvert, string sourceSolutionContents)
12+
{
13+
foreach (var (projFilePath, projDirPath) in projectsToConvert) {
14+
var projFilename = Path.GetFileName(projFilePath);
15+
16+
var newProjFilename = PathConverter.TogglePathExtension(projFilename);
17+
18+
var projPath = PathConverter.GetFileDirPath(projFilename, projDirPath);
19+
var newProjPath = PathConverter.GetFileDirPath(newProjFilename, projDirPath);
20+
21+
var projPathEscaped = Regex.Escape(projPath);
22+
23+
yield return (projPathEscaped, newProjPath, false);
24+
if (!string.IsNullOrWhiteSpace(sourceSolutionContents) && GetProjectGuidReplacement(projPathEscaped, sourceSolutionContents) is { } replacement) yield return replacement;
25+
}
26+
}
27+
28+
private static (string Find, string Replace, bool FirstOnly)? GetProjectGuidReplacement(string projPath, string contents)
29+
{
30+
var projGuidRegex = new Regex(projPath + @""", ""({[0-9A-Fa-f\-]{32,36}})("")");
31+
var projGuidMatch = projGuidRegex.Match(contents);
32+
if (!projGuidMatch.Success) return null;
33+
34+
var oldGuid = projGuidMatch.Groups[1].Value;
35+
var newGuid = GetDeterministicGuidFrom(new Guid(oldGuid));
36+
return (oldGuid, newGuid.ToString("B").ToUpperInvariant(), false);
37+
}
38+
39+
private static Guid GetDeterministicGuidFrom(Guid guidToConvert)
40+
{
41+
var codeConverterStaticGuid = new Guid("{B224816B-CC58-4FF1-8258-CA7E629734A0}");
42+
var deterministicNewBytes = codeConverterStaticGuid.ToByteArray().Zip(guidToConvert.ToByteArray(),
43+
(fromFirst, fromSecond) => (byte)(fromFirst ^ fromSecond));
44+
return new Guid(deterministicNewBytes.ToArray());
45+
}
46+
}
47+
}

CodeConverter/Shared/TextReplacementConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public static ConversionResult ConversionResultFromReplacements(this FileInfo fi
1313
var newProjectText = File.ReadAllText(filePath.FullName);
1414
newProjectText = newProjectText.Replace(replacements);
1515
string withReplacements = postReplacementTransform(newProjectText);
16-
return new ConversionResult(withReplacements) { SourcePathOrNull = filePath.FullName, IsIdentity = newProjectText == withReplacements};
16+
return new ConversionResult(withReplacements) { SourcePathOrNull = filePath.FullName, IsIdentity = newProjectText == withReplacements };
1717
}
1818

1919
public static string Replace(this string originalText, IEnumerable<(string Find, string Replace, bool FirstOnly)> replacements)
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
using System.Linq;
2+
using ICSharpCode.CodeConverter.Shared;
3+
using Xunit;
4+
5+
namespace ICSharpCode.CodeConverter.Tests.LanguageAgnostic
6+
{
7+
public class SolutionFileTextEditorTests
8+
{
9+
[Fact]
10+
public void WhenInSolutionBaseDirThenUpdated()
11+
{
12+
AssertProjectReplacement(SolutionProjectReferenceLine("VbLibrary", @"VbLibrary.vbproj"),
13+
UpdatedSolutionProjectReferenceLine("VbLibrary", @"VbLibrary.csproj"),
14+
(FilePath: @"C:\MySolution\VbLibrary.vbproj", DirectoryPath: @"C:\MySolution\"));
15+
}
16+
[Fact]
17+
public void WhenInProjectFolderThenUpdated()
18+
{
19+
AssertProjectReplacement(SolutionProjectReferenceLine("VbLibrary", @"VbLibrary\VbLibrary.vbproj"),
20+
UpdatedSolutionProjectReferenceLine("VbLibrary", @"VbLibrary\VbLibrary.csproj"),
21+
(FilePath: @"C:\MySolution\VbLibrary\VbLibrary.vbproj", DirectoryPath: @"C:\MySolution\VbLibrary\"));
22+
}
23+
24+
[Fact]
25+
public void GivenDifferentLibraryThenNotUpdated()
26+
{
27+
string unaffectedProject = SolutionProjectReferenceLine("Prefix.VbLibrary", @"Prefix.VbLibrary\Prefix.VbLibrary.vbproj");
28+
AssertProjectReplacement(unaffectedProject, unaffectedProject, (FilePath: @"C:\MySolution\VbLibrary\VbLibrary.vbproj", DirectoryPath: @"C:\MySolution\VbLibrary\"));
29+
}
30+
31+
[Fact]
32+
public void GivenDifferentLibraryThenNotUpdated2()
33+
{
34+
string unaffectedProject = SolutionProjectReferenceLine("VbLibrary", @"VbLibrary\VbLibrary.vbproj");
35+
AssertProjectReplacement(unaffectedProject, unaffectedProject, (FilePath: @"C:\MySolution\Prefix.VbLibrary\Prefix.VbLibrary.vbproj", DirectoryPath: @"C:\MySolution\Prefix.VbLibrary\"));
36+
}
37+
38+
[Fact]
39+
public void GivenDifferentLibraryWhenInSolutionBaseDirThenNotUpdated()
40+
{
41+
string unaffectedProject = SolutionProjectReferenceLine("Prefix.VbLibrary", @"Prefix.VbLibrary.vbproj");
42+
AssertProjectReplacement(unaffectedProject, unaffectedProject, (FilePath: @"C:\MySolution\VbLibrary.vbproj", DirectoryPath: @"C:\MySolution\"));
43+
}
44+
45+
[Fact]
46+
public void GivenDifferentLibraryWhenInSolutionBaseDirThenNotUpdated2()
47+
{
48+
string unaffectedProject = SolutionProjectReferenceLine("VbLibrary", @"VbLibrary.vbproj");
49+
AssertProjectReplacement(unaffectedProject, unaffectedProject, (FilePath: @"C:\MySolution\Prefix.VbLibrary.vbproj", DirectoryPath: @"C:\MySolution\"));
50+
}
51+
52+
private static string SolutionProjectReferenceLine(string projectName, string projRelativePath) =>
53+
$@"Project(""{{F184B08F-C81C-45F6-A57F-5ABD9991F28F}}"") = ""{projectName}"", ""{projRelativePath}"", ""{{CFAB82CD-BA17-4F08-99E2-403FADB0C46A}}""";
54+
55+
private static string UpdatedSolutionProjectReferenceLine(string projectName, string projRelativePath) =>
56+
$@"Project(""{{F184B08F-C81C-45F6-A57F-5ABD9991F28F}}"") = ""{projectName}"", ""{projRelativePath}"", ""{{7D8F03A6-764F-00F9-1BBA-8A41CF27F0CA}}""";
57+
58+
private static void AssertProjectReplacement(string originalText, string expectedOutput, params (string FilePath, string DirectoryPath)[] projects)
59+
{
60+
var replacements = SolutionFileTextEditor.GetProjectReferenceReplacements(projects, originalText).ToList();
61+
var actualOutput = TextReplacementConverter.Replace(originalText, replacements);
62+
Assert.Equal(Utils.HomogenizeEol(expectedOutput), Utils.HomogenizeEol(actualOutput));
63+
}
64+
}
65+
}

0 commit comments

Comments
 (0)