SDT/tests/DevTool.Tests/PrereqInstallerServiceTests.cs
2026-03-01 20:52:56 -06:00

160 lines
5.8 KiB
C#

using Sdt.Config;
using Sdt.Core;
using Xunit;
namespace DevTool.Tests;
public sealed class PrereqInstallerServiceTests
{
[Fact]
public async Task PreferredInstallCommands_AreUsedFirst()
{
var svc = new PrereqInstallerService();
var cfg = new DevToolConfig
{
Tooling = new ToolingConfig
{
Tools =
[
new ToolInstallDefinition
{
Tool = "dotnet",
PreferredInstallCommands =
[
"echo install dotnet",
"dotnet --info"
]
}
]
}
};
var plan = await svc.GetInstallPlanAsync("dotnet", Directory.GetCurrentDirectory(), cfg);
Assert.True(plan.Supported);
Assert.Equal("dotnet", plan.Tool);
Assert.Equal(2, plan.Commands.Count);
Assert.Equal("echo", plan.Commands[0].Command);
Assert.Equal("dotnet", plan.Commands[1].Command);
}
[Fact]
public async Task PreferredWingetCommand_IsNormalizedForNonInteractiveInstall()
{
var svc = new PrereqInstallerService();
var cfg = new DevToolConfig
{
Tooling = new ToolingConfig
{
Tools =
[
new ToolInstallDefinition
{
Tool = "dotnet",
PreferredInstallCommands =
[
"winget install Microsoft.DotNet.SDK.10"
]
}
]
}
};
var plan = await svc.GetInstallPlanAsync("dotnet", Directory.GetCurrentDirectory(), cfg);
var args = plan.Commands[0].Args;
Assert.Contains("--accept-package-agreements", args, StringComparer.OrdinalIgnoreCase);
Assert.Contains("--accept-source-agreements", args, StringComparer.OrdinalIgnoreCase);
Assert.Contains("--disable-interactivity", args, StringComparer.OrdinalIgnoreCase);
Assert.Contains("--source", args, StringComparer.OrdinalIgnoreCase);
}
[Fact]
public async Task PreferredShellAptCommand_IsNormalizedForNonInteractiveInstall()
{
var svc = new PrereqInstallerService();
var cfg = new DevToolConfig
{
Tooling = new ToolingConfig
{
Tools =
[
new ToolInstallDefinition
{
Tool = "git",
PreferredInstallCommands =
[
"sh -c \"sudo apt-get update && sudo apt-get install git\""
]
}
]
}
};
var plan = await svc.GetInstallPlanAsync("git", Directory.GetCurrentDirectory(), cfg);
Assert.Equal("sh", plan.Commands[0].Command, ignoreCase: true);
Assert.True(plan.Commands[0].Args.Count >= 2);
var script = plan.Commands[0].Args[1];
Assert.Contains("DEBIAN_FRONTEND=noninteractive", script, StringComparison.OrdinalIgnoreCase);
Assert.Contains("apt-get install -y", script, StringComparison.OrdinalIgnoreCase);
}
[Fact]
public async Task DiagInstallPlanFailure_FallsBackToTemplatePlan()
{
var root = Path.Combine(Path.GetTempPath(), "sdt-prereq-" + Guid.NewGuid().ToString("N"));
var scripts = Path.Combine(root, "scripts");
Directory.CreateDirectory(scripts);
await File.WriteAllTextAsync(Path.Combine(scripts, "diag.py"), "import sys\nsys.exit(2)\n");
var svc = new PrereqInstallerService();
var plan = await svc.GetInstallPlanAsync("npm", root, new DevToolConfig());
Assert.True(plan.Supported);
Assert.NotEmpty(plan.Commands);
Assert.Contains("fallback", plan.Summary, StringComparison.OrdinalIgnoreCase);
}
[Fact]
public async Task DiagInstallPlanInvalidJson_FallsBackToTemplatePlan()
{
var root = Path.Combine(Path.GetTempPath(), "sdt-prereq-" + Guid.NewGuid().ToString("N"));
var scripts = Path.Combine(root, "scripts");
Directory.CreateDirectory(scripts);
await File.WriteAllTextAsync(Path.Combine(scripts, "diag.py"), "print('not-json')\n");
var svc = new PrereqInstallerService();
var plan = await svc.GetInstallPlanAsync("dotnet", root, new DevToolConfig());
Assert.True(plan.Supported);
Assert.NotEmpty(plan.Commands);
Assert.Contains("fallback", plan.Summary, StringComparison.OrdinalIgnoreCase);
}
[Fact]
public async Task TauriFallbackPlan_IsMultiStepAndClear()
{
var root = Path.Combine(Path.GetTempPath(), "sdt-prereq-" + Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(root);
var svc = new PrereqInstallerService();
var plan = await svc.GetInstallPlanAsync("tauri", root, new DevToolConfig());
Assert.True(plan.Supported);
Assert.True(plan.Commands.Count >= 3);
Assert.Contains("tauri", plan.Summary, StringComparison.OrdinalIgnoreCase);
}
[Fact]
public async Task TauriFallbackPlan_IncludesRustAndCliCommands()
{
var root = Path.Combine(Path.GetTempPath(), "sdt-prereq-" + Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(root);
var svc = new PrereqInstallerService();
var plan = await svc.GetInstallPlanAsync("tauri", root, new DevToolConfig());
Assert.Contains(plan.Commands, c => c.Args.Any(a => a.Contains("rustup", StringComparison.OrdinalIgnoreCase)));
Assert.Contains(plan.Commands, c => c.Args.Any(a => a.Contains("@tauri-apps/cli", StringComparison.OrdinalIgnoreCase)));
}
}