using Sdt.Config; using Xunit; namespace DevTool.Tests; public sealed class WorkspaceDefaultsTests { [Fact] public void ConfigLoader_AppliesWorkspaceDefaults_FromAncestorDirectory() { var workspaceRoot = CreateTempDir("sdt-ws-defaults-"); var projectRoot = Path.Combine(workspaceRoot, "proj-a"); Directory.CreateDirectory(projectRoot); File.WriteAllText(Path.Combine(workspaceRoot, WorkspaceLoader.FileName), """ { "name": "Test Workspace", "projects": [] } """); File.WriteAllText(Path.Combine(workspaceRoot, ConfigLoader.WorkspaceDefaultsFileName), """ { "toolchains": { "node": { "packageManager": "pnpm", "workingDir": "frontend" } }, "env": [ { "key": "DOTNET_ENVIRONMENT", "description": "default env", "default": "Development", "options": ["Development", "Production"] } ] } """); File.WriteAllText(Path.Combine(projectRoot, "sdtconfig-project-a.json"), """ { "name": "Project A", "version": "1.0.0", "workflows": [ { "id": "build", "label": "Build", "description": "Build app", "group": "Build", "dependsOn": [], "steps": [ { "id": "build-step", "label": "dotnet build", "command": "dotnet", "args": ["build"], "workingDir": "." } ] } ] } """); var loaded = ConfigLoader.FindAndLoad(projectRoot); Assert.NotNull(loaded); Assert.Equal("pnpm", loaded!.Config.Toolchains?.Node?.PackageManager); Assert.Equal("frontend", loaded.Config.Toolchains?.Node?.WorkingDir); Assert.Single(loaded.Config.Env); Assert.Contains(loaded.Warnings, w => w.Contains("Applied workspace defaults", StringComparison.OrdinalIgnoreCase)); } [Fact] public void ConfigLoader_ProjectValuesOverrideWorkspaceDefaults() { var workspaceRoot = CreateTempDir("sdt-ws-override-"); var projectRoot = Path.Combine(workspaceRoot, "proj-b"); Directory.CreateDirectory(projectRoot); File.WriteAllText(Path.Combine(workspaceRoot, WorkspaceLoader.FileName), """ { "name": "Test Workspace", "projects": [] } """); File.WriteAllText(Path.Combine(workspaceRoot, ConfigLoader.WorkspaceDefaultsFileName), """ { "name": "Workspace Defaults", "workflows": [ { "id": "from-defaults", "label": "Defaults Workflow", "description": "", "group": "General", "dependsOn": [], "steps": [] } ], "debug": { "diagnostics": { "enabled": true, "outputDir": ".sdt/workspace-debug", "includeAllEnv": true, "bundleOnFailure": true } } } """); File.WriteAllText(Path.Combine(projectRoot, "sdtconfig-project-b.json"), """ { "name": "Project B", "version": "1.0.0", "workflows": [ { "id": "project-workflow", "label": "Project Workflow", "description": "Only this one should remain", "group": "Build", "dependsOn": [], "steps": [] } ], "debug": { "diagnostics": { "enabled": false } } } """); var loaded = ConfigLoader.FindAndLoad(projectRoot); Assert.NotNull(loaded); Assert.Equal("Project B", loaded!.Config.Name); Assert.Single(loaded.Config.Workflows); Assert.Equal("project-workflow", loaded.Config.Workflows[0].Id); Assert.NotNull(loaded.Config.Debug); Assert.NotNull(loaded.Config.Debug!.Diagnostics); Assert.False(loaded.Config.Debug.Diagnostics.Enabled); Assert.Equal(".sdt/workspace-debug", loaded.Config.Debug.Diagnostics.OutputDir); Assert.True(loaded.Config.Debug.Diagnostics.IncludeAllEnv); } private static string CreateTempDir(string prefix) { var path = Path.Combine(Path.GetTempPath(), prefix + Guid.NewGuid().ToString("N")); Directory.CreateDirectory(path); return path; } }