Initial commit: Nix WSL Wrapper project with DDD, Clean Code, and tests
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using Moq;
|
||||
using NixWslWrapper.Cli;
|
||||
using NixWslWrapper.Core.Domain;
|
||||
using NixWslWrapper.Core.Interfaces;
|
||||
using Xunit;
|
||||
|
||||
namespace NixWslWrapper.Tests
|
||||
{
|
||||
public class CliTests
|
||||
{
|
||||
[Fact]
|
||||
public void CliController_ForwardArguments_ShouldReturnExecutorExitCode()
|
||||
{
|
||||
var mockExecutor = new Mock<ICommandExecutor>();
|
||||
var expectedResult = new ExecutionResult(42);
|
||||
mockExecutor
|
||||
.Setup(m => m.Execute(It.IsAny<NixArguments>(), It.IsAny<WslTarget>()))
|
||||
.Returns(expectedResult);
|
||||
|
||||
var controller = new CliController(mockExecutor.Object);
|
||||
string[] cliArgs = new[] { "run", "nixpkgs#hello" };
|
||||
|
||||
int exitCode = controller.Run(cliArgs);
|
||||
|
||||
Assert.Equal(42, exitCode);
|
||||
mockExecutor.Verify(m => m.Execute(
|
||||
It.Is<NixArguments>(a => a.RawArguments.Length == 2 && a.RawArguments[0] == "run"),
|
||||
It.IsAny<WslTarget>()
|
||||
), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CliController_HelpMenuFlag_ShouldReturnZeroImmediately()
|
||||
{
|
||||
var mockExecutor = new Mock<ICommandExecutor>();
|
||||
var controller = new CliController(mockExecutor.Object);
|
||||
string[] cliArgs = new[] { "--wsl-help" };
|
||||
|
||||
int exitCode = controller.Run(cliArgs);
|
||||
|
||||
Assert.Equal(0, exitCode);
|
||||
mockExecutor.Verify(m => m.Execute(It.IsAny<NixArguments>(), It.IsAny<WslTarget>()), Times.Never);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using NixWslWrapper.Core.Domain;
|
||||
using Xunit;
|
||||
|
||||
namespace NixWslWrapper.Tests
|
||||
{
|
||||
public class CoreTests
|
||||
{
|
||||
[Fact]
|
||||
public void WslTarget_ValidParameters_ShouldConstructCorrectly()
|
||||
{
|
||||
var target = new WslTarget("Debian", "root", "/some/path");
|
||||
Assert.Equal("Debian", target.Distribution);
|
||||
Assert.Equal("root", target.User);
|
||||
Assert.Equal("/some/path", target.NixProfilePath);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("", "root", "/path")]
|
||||
[InlineData("Debian", "", "/path")]
|
||||
[InlineData("Debian", "root", "")]
|
||||
[InlineData(null, "root", "/path")]
|
||||
[InlineData("Debian", null, "/path")]
|
||||
[InlineData("Debian", "root", null)]
|
||||
public void WslTarget_InvalidParameters_ShouldThrowArgumentException(string? distro, string? user, string? profile)
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => new WslTarget(distro!, user!, profile!));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WslTarget_Equality_ShouldBeTrueForSameValues()
|
||||
{
|
||||
var target1 = new WslTarget("Debian", "root", "/path");
|
||||
var target2 = new WslTarget("debian", "ROOT", "/path"); // case-insensitive for distro/user
|
||||
Assert.Equal(target1, target2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NixArguments_EmptyArgs_ShouldReturnEmptyEscapedString()
|
||||
{
|
||||
var args = new NixArguments(Array.Empty<string>());
|
||||
Assert.Equal(string.Empty, args.ToEscapedString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NixArguments_WithSpecialCharacters_ShouldEscapeDoubleQuotes()
|
||||
{
|
||||
var args = new NixArguments(new[] { "run", "nixpkgs#hello", "--argstr", "msg", "hello \"world\"" });
|
||||
string escaped = args.ToEscapedString();
|
||||
Assert.Equal("\"run\" \"nixpkgs#hello\" \"--argstr\" \"msg\" \"hello \\\"world\\\"\"", escaped);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExecutionResult_Success_ShouldSetCorrectProperties()
|
||||
{
|
||||
var result = ExecutionResult.Success();
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal(0, result.ExitCode);
|
||||
Assert.Null(result.ErrorMessage);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExecutionResult_Failure_ShouldSetCorrectProperties()
|
||||
{
|
||||
var result = ExecutionResult.Failure(5, "Access Denied");
|
||||
Assert.False(result.IsSuccess);
|
||||
Assert.Equal(5, result.ExitCode);
|
||||
Assert.Equal("Access Denied", result.ErrorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
global using Xunit;
|
||||
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using NixWslWrapper.Infrastructure.IO;
|
||||
using NixWslWrapper.Infrastructure.Executors;
|
||||
using Xunit;
|
||||
|
||||
namespace NixWslWrapper.Tests
|
||||
{
|
||||
public class InfrastructureTests
|
||||
{
|
||||
[Fact]
|
||||
public void ThreadedStreamCopier_ValidStream_ShouldCopyEntireContent()
|
||||
{
|
||||
var content = "Hello, Nix WSL Wrapper! Stream copying should work flawlessly.";
|
||||
byte[] bytes = Encoding.UTF8.GetBytes(content);
|
||||
using var input = new MemoryStream(bytes);
|
||||
using var output = new MemoryStream();
|
||||
|
||||
var copier = new ThreadedStreamCopier(64); // small buffer to force multiple reads
|
||||
copier.Copy(input, output);
|
||||
|
||||
byte[] resultBytes = output.ToArray();
|
||||
string result = Encoding.UTF8.GetString(resultBytes);
|
||||
|
||||
Assert.Equal(content, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ProcessBuilder_ValidConfiguration_ShouldBuildCorrectProcessStartInfo()
|
||||
{
|
||||
var builder = new ProcessBuilder()
|
||||
.SetFileName("my-app.exe")
|
||||
.SetArguments("--arg1 val1")
|
||||
.RedirectInput(true)
|
||||
.RedirectOutput(true)
|
||||
.RedirectError(true)
|
||||
.UseShellExecute(false)
|
||||
.CreateNoWindow(true);
|
||||
|
||||
var startInfo = builder.Build();
|
||||
|
||||
Assert.Equal("my-app.exe", startInfo.FileName);
|
||||
Assert.Equal("--arg1 val1", startInfo.Arguments);
|
||||
Assert.True(startInfo.RedirectStandardInput);
|
||||
Assert.True(startInfo.RedirectStandardOutput);
|
||||
Assert.True(startInfo.RedirectStandardError);
|
||||
Assert.False(startInfo.UseShellExecute);
|
||||
Assert.True(startInfo.CreateNoWindow);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0" />
|
||||
<PackageReference Include="Moq" Version="4.20.72" />
|
||||
<PackageReference Include="xunit" Version="2.4.2" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.0">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\NixWslWrapper.Core\NixWslWrapper.Core.csproj" />
|
||||
<ProjectReference Include="..\..\src\NixWslWrapper.Infrastructure\NixWslWrapper.Infrastructure.csproj" />
|
||||
<ProjectReference Include="..\..\src\NixWslWrapper.Cli\NixWslWrapper.Cli.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user