- introduce `sdt` subcommands for run, debug, setup, env, favorite, and explain - add project/workspace discovery plus config bootstrap and migration helpers - expand tests for CLI parsing, project role detection, and headless flows
99 lines
3.8 KiB
C#
99 lines
3.8 KiB
C#
using Sdt.Config;
|
|
using Sdt.Core;
|
|
using Xunit;
|
|
|
|
namespace DevTool.Tests;
|
|
|
|
public sealed class ProjectRoleDetectorTests
|
|
{
|
|
[Fact]
|
|
public void Detect_FindsSharedProjectRoles()
|
|
{
|
|
var root = CreateTempDir();
|
|
Directory.CreateDirectory(Path.Combine(root, "ui", "src-tauri"));
|
|
File.WriteAllText(Path.Combine(root, "SidecarService.csproj"), "<Project Sdk=\"Microsoft.NET.Sdk\" />");
|
|
File.WriteAllText(Path.Combine(root, "GatewayService.csproj"), "<Project Sdk=\"Microsoft.NET.Sdk\" />");
|
|
File.WriteAllText(Path.Combine(root, "ui", "package.json"), """{ "name": "demo-ui", "scripts": { "build": "echo build", "tauri": "echo tauri" } }""");
|
|
File.WriteAllText(Path.Combine(root, "ui", "src-tauri", "tauri.conf.json"), "{}");
|
|
File.WriteAllText(Path.Combine(root, "demo.csproj"), """
|
|
<Project Sdk="Microsoft.NET.Sdk">
|
|
<PropertyGroup>
|
|
<OutputType>Exe</OutputType>
|
|
<TargetFramework>net10.0</TargetFramework>
|
|
<AssemblyName>sdt</AssemblyName>
|
|
</PropertyGroup>
|
|
</Project>
|
|
""");
|
|
|
|
var roles = ProjectRoleDetector.Detect(root, Path.Combine("ui"), "demo");
|
|
|
|
Assert.Equal("SidecarService.csproj", roles.UniqueSidecarProject, ignoreCase: true);
|
|
Assert.Equal("GatewayService.csproj", roles.UniqueGatewayProject, ignoreCase: true);
|
|
Assert.Equal("ui/package.json", roles.NodeAppPackageJsonRelativePath, ignoreCase: true);
|
|
Assert.Equal("ui/src-tauri/tauri.conf.json", roles.TauriConfigRelativePath, ignoreCase: true);
|
|
Assert.NotNull(roles.PrimaryExecutableDotnetProject);
|
|
Assert.Equal("sdt", roles.PrimaryExecutableDotnetProject!.DisplayName, ignoreCase: true);
|
|
}
|
|
|
|
[Fact]
|
|
public void IsWorkflowApplicable_HidesTauriWorkflow_WhenNoTauriAppExists()
|
|
{
|
|
var root = CreateTempDir();
|
|
var scripts = Path.Combine(root, "scripts");
|
|
Directory.CreateDirectory(scripts);
|
|
Directory.CreateDirectory(Path.Combine(root, "ui"));
|
|
File.WriteAllText(Path.Combine(scripts, "publish-app.py"), "print('ok')");
|
|
File.WriteAllText(Path.Combine(root, "ui", "package.json"), """{ "name": "demo-ui", "scripts": { "build": "echo build" } }""");
|
|
|
|
var web = new WorkflowDefinition
|
|
{
|
|
Id = "web",
|
|
Label = "Build Web",
|
|
RequireFiles = ["scripts/publish-app.py", "ui/package.json"],
|
|
Steps =
|
|
[
|
|
new WorkflowStep
|
|
{
|
|
Id = "web:run",
|
|
Command = "python",
|
|
Args = ["scripts/publish-app.py", "--target", "web"],
|
|
WorkingDir = "."
|
|
}
|
|
]
|
|
};
|
|
var tauri = new WorkflowDefinition
|
|
{
|
|
Id = "tauri",
|
|
Label = "Build Tauri",
|
|
RequireFiles = ["scripts/publish-app.py", "ui/package.json", "ui/src-tauri/tauri.conf.json"],
|
|
Steps =
|
|
[
|
|
new WorkflowStep
|
|
{
|
|
Id = "tauri:run",
|
|
Command = "python",
|
|
Args = ["scripts/publish-app.py", "--target", "tauri"],
|
|
WorkingDir = "."
|
|
}
|
|
]
|
|
};
|
|
|
|
var map = new Dictionary<string, WorkflowDefinition>(StringComparer.OrdinalIgnoreCase)
|
|
{
|
|
[web.Id] = web,
|
|
[tauri.Id] = tauri,
|
|
};
|
|
var roles = ProjectRoleDetector.Detect(root, "ui", "demo");
|
|
|
|
Assert.True(ProjectRoleDetector.IsWorkflowApplicable(root, web, map, roles));
|
|
Assert.False(ProjectRoleDetector.IsWorkflowApplicable(root, tauri, map, roles));
|
|
}
|
|
|
|
private static string CreateTempDir()
|
|
{
|
|
var path = Path.Combine(Path.GetTempPath(), "sdt-role-detector-" + Guid.NewGuid().ToString("N"));
|
|
Directory.CreateDirectory(path);
|
|
return path;
|
|
}
|
|
}
|