using FluentAssertions; namespace SatelliteProvider.Tests; public class ToolingConfigurationTests { [Fact] public void EditorConfig_ExistsAtRoot_AZ372_AC1() { var path = LocateRepoFile(".editorconfig"); path.Should().NotBeNull(".editorconfig must exist at the workspace root for `dotnet format` to honor formatting rules"); var content = File.ReadAllText(path!); content.Should().Contain("root = true"); content.Should().Contain("indent_style = space"); content.Should().Contain("end_of_line = lf"); content.Should().Contain("insert_final_newline = true"); content.Should().Contain("trim_trailing_whitespace = true"); } [Fact] public void EditorConfig_DefinesInitialAnalyzerRuleset_AZ372_AC3() { var path = LocateRepoFile(".editorconfig"); path.Should().NotBeNull(); var content = File.ReadAllText(path!); content.Should().Contain("dotnet_diagnostic.CA1001.severity = warning"); content.Should().Contain("dotnet_diagnostic.CA1051.severity = warning"); content.Should().Contain("dotnet_diagnostic.CA1816.severity = warning"); content.Should().Contain("dotnet_diagnostic.CA2227.severity = warning"); } [Fact] public void DirectoryBuildProps_ExistsAtRoot_AZ372_AC3() { var path = LocateRepoFile("Directory.Build.props"); path.Should().NotBeNull("Directory.Build.props centralizes analyzer settings for every csproj"); var content = File.ReadAllText(path!); content.Should().Contain("true"); content.Should().Contain("latest"); content.Should().Contain("None", "AnalysisMode=None ensures only rules explicitly enabled in .editorconfig fire; protects against analyzer flood"); } [Fact] public void RunTestsScript_WiresFormatVerify_AZ372_AC1() { var path = LocateRepoFile(Path.Combine("scripts", "run-tests.sh")); path.Should().NotBeNull(); var content = File.ReadAllText(path!); content.Should().Contain("dotnet format whitespace"); content.Should().Contain("--verify-no-changes", "AC-1 requires the script to gate on whitespace conformance via dotnet format"); } [Fact] public void RunTestsScript_CollectsCoverage_AZ372_AC2() { var path = LocateRepoFile(Path.Combine("scripts", "run-tests.sh")); path.Should().NotBeNull(); var content = File.ReadAllText(path!); content.Should().Contain("XPlat Code Coverage"); } [Fact] public void TestProject_ReferencesCoverletCollector_AZ372_AC2() { var path = LocateRepoFile(Path.Combine("SatelliteProvider.Tests", "SatelliteProvider.Tests.csproj")); path.Should().NotBeNull(); var content = File.ReadAllText(path!); content.Should().Contain("coverlet.collector", "Coverlet collector is the data collector that produces XPlat Code Coverage reports"); } private static string? LocateRepoFile(string relativePath) { var dir = new DirectoryInfo(Directory.GetCurrentDirectory()); while (dir is not null) { var candidate = Path.Combine(dir.FullName, relativePath); if (File.Exists(candidate)) { return candidate; } dir = dir.Parent; } return null; } }