using System.Runtime.CompilerServices; using System.Xml.Linq; namespace AcDream.Launcher.Core.Tests; // Campaign LA plan §LA3 review finding F5: AcDream.Launcher.Core's entire // premise (spec §LA3, SessionConfigDocument.cs's "PINNED CONTRACT" remarks) // is being the BCL-plus-Platform-only assembly the external Avalonia // launcher (LA4) can reference without pulling in any game-solution // dependency. That contract is what this guard enforces — the csproj must // declare exactly one ProjectReference (AcDream.Platform) and zero // PackageReference entries, forever, in the same spirit as Platform's, // Runtime's, and Headless's dependency-boundary guards. public sealed class LauncherCoreDependencyBoundaryTests { [Fact] public void LauncherCoreProjectReferencesOnlyPlatformAndDeclaresNoPackages() { string repositoryRoot = FindRepositoryRoot(); string projectPath = Path.Combine( repositoryRoot, "src", "AcDream.Launcher.Core", "AcDream.Launcher.Core.csproj"); var project = XDocument.Load(projectPath); var projectReferences = project.Descendants("ProjectReference") .Select(element => element.Attribute("Include")?.Value) // The csproj is authored with Windows-style "..\Foo\Foo.csproj" // separators; Path.GetFileName only recognizes the platform's // own separator, so on Linux it would return the whole // relative path unchanged instead of just the filename. // Normalizing to '/' first keeps this assertion // platform-agnostic (this project's tests run under both // native Windows and WSL — see Campaign LA plan §LA3 review // finding F5's acceptance). .Select(include => include is null ? null : Path.GetFileName(include.Replace('\\', '/'))) .ToList(); Assert.Equal(["AcDream.Platform.csproj"], projectReferences); Assert.Empty(project.Descendants("PackageReference")); } private static string FindRepositoryRoot( [CallerFilePath] string sourcePath = "") { string[] starts = { Path.GetDirectoryName(sourcePath) ?? string.Empty, Directory.GetCurrentDirectory(), AppContext.BaseDirectory, }; foreach (string start in starts) { if (string.IsNullOrEmpty(start)) { continue; } var directory = new DirectoryInfo(start); while (directory is not null) { if (File.Exists(Path.Combine( directory.FullName, "AcDream.slnx"))) { return directory.FullName; } directory = directory.Parent; } } throw new DirectoryNotFoundException( "Could not find AcDream.slnx above the source, working, or output directory."); } }