SOMS/SolutionCleanupTool.Tests/SolutionParserTests.cs

175 lines
6.5 KiB
C#
Raw Normal View History

2025-12-31 14:25:09 +08:00
using Microsoft.Extensions.Logging;
using SolutionCleanupTool.Models;
using SolutionCleanupTool.Services;
using System;
using System.IO;
using System.Linq;
using Xunit;
namespace SolutionCleanupTool.Tests
{
/// <summary>
/// Unit tests for SolutionParser functionality
/// </summary>
public class SolutionParserTests : IDisposable
{
private readonly SolutionParser _parser;
private readonly string _tempDirectory;
private readonly ILogger<SolutionParser> _logger;
public SolutionParserTests()
{
// Create a mock logger for testing
var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole());
_logger = loggerFactory.CreateLogger<SolutionParser>();
_parser = new SolutionParser(_logger);
// Create a temporary directory for test files
_tempDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(_tempDirectory);
}
[Fact]
public void ParseSolution_WithValidSolutionFile_ShouldReturnSolutionModel()
{
// Arrange
var solutionContent = @"
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30114.105
MinimumVisualStudioVersion = 10.0.40219.1
Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""TestProject1"", ""TestProject1\TestProject1.csproj"", ""{12345678-1234-1234-1234-123456789012}""
EndProject
Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""TestProject2"", ""TestProject2\TestProject2.csproj"", ""{87654321-4321-4321-4321-210987654321}""
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{12345678-1234-1234-1234-123456789012}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{12345678-1234-1234-1234-123456789012}.Debug|Any CPU.Build.0 = Debug|Any CPU
EndGlobalSection
EndGlobal
";
var solutionPath = Path.Combine(_tempDirectory, "TestSolution.sln");
File.WriteAllText(solutionPath, solutionContent);
// Act
var result = _parser.ParseSolution(solutionPath);
// Assert
Assert.NotNull(result);
Assert.Equal(solutionPath, result.FilePath);
Assert.Equal(2, result.Projects.Count);
var project1 = result.Projects.FirstOrDefault(p => p.Name == "TestProject1");
Assert.NotNull(project1);
Assert.Equal("TestProject1\\TestProject1.csproj", project1.RelativePath);
Assert.Equal(new Guid("12345678-1234-1234-1234-123456789012"), project1.ProjectGuid);
var project2 = result.Projects.FirstOrDefault(p => p.Name == "TestProject2");
Assert.NotNull(project2);
Assert.Equal("TestProject2\\TestProject2.csproj", project2.RelativePath);
Assert.Equal(new Guid("87654321-4321-4321-4321-210987654321"), project2.ProjectGuid);
}
[Fact]
public void ParseSolution_WithNonExistentFile_ShouldThrowFileNotFoundException()
{
// Arrange
var nonExistentPath = Path.Combine(_tempDirectory, "NonExistent.sln");
// Act & Assert
Assert.Throws<FileNotFoundException>(() => _parser.ParseSolution(nonExistentPath));
}
[Fact]
public void ParseSolution_WithNullPath_ShouldThrowArgumentException()
{
// Act & Assert
Assert.Throws<ArgumentException>(() => _parser.ParseSolution(null));
}
[Fact]
public void ParseSolution_WithEmptyPath_ShouldThrowArgumentException()
{
// Act & Assert
Assert.Throws<ArgumentException>(() => _parser.ParseSolution(string.Empty));
}
[Fact]
public void ExtractProjectReferences_WithValidSolution_ShouldReturnProjectReferences()
{
// Arrange
var solution = new SolutionModel
{
FilePath = "TestSolution.sln",
Projects = new List<ProjectReference>
{
new ProjectReference
{
Name = "TestProject1",
RelativePath = "TestProject1\\TestProject1.csproj",
AbsolutePath = Path.Combine(_tempDirectory, "TestProject1", "TestProject1.csproj"),
ProjectGuid = Guid.NewGuid(),
ProjectTypeGuid = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
}
}
};
// Act
var result = _parser.ExtractProjectReferences(solution);
// Assert
Assert.NotNull(result);
Assert.Single(result);
Assert.Equal("TestProject1", result[0].Name);
Assert.False(result[0].Exists); // File doesn't exist in temp directory
}
[Fact]
public void ExtractProjectReferences_WithNullSolution_ShouldThrowArgumentNullException()
{
// Act & Assert
Assert.Throws<ArgumentNullException>(() => _parser.ExtractProjectReferences(null));
}
[Fact]
public void ParseSolution_WithSolutionFolders_ShouldIgnoreSolutionFolders()
{
// Arrange
var solutionContent = @"
Microsoft Visual Studio Solution File, Format Version 12.00
Project(""{2150E333-8FDC-42A3-9474-1A3956D46DE8}"") = ""SolutionFolder"", ""SolutionFolder"", ""{FOLDER-GUID-1234-1234-1234-123456789012}""
EndProject
Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""RealProject"", ""RealProject\RealProject.csproj"", ""{12345678-1234-1234-1234-123456789012}""
EndProject
Global
EndGlobal
";
var solutionPath = Path.Combine(_tempDirectory, "TestSolutionWithFolders.sln");
File.WriteAllText(solutionPath, solutionContent);
// Act
var result = _parser.ParseSolution(solutionPath);
// Assert
Assert.NotNull(result);
Assert.Single(result.Projects); // Should only have the real project, not the solution folder
Assert.Equal("RealProject", result.Projects[0].Name);
}
public void Dispose()
{
// Clean up temporary directory
if (Directory.Exists(_tempDirectory))
{
Directory.Delete(_tempDirectory, true);
}
}
}
}