using System; using System.IO; using System.Linq; using Xunit; namespace ytLive.Tests; /// /// The shipped binary is LlamaCasty.exe (renamed 2026-11-01, before the first Steam /// depot). Two things have to agree for that to be true, and neither fails the build when it /// doesn't: /// /// /// The assembly name comes from ytLive.csproj and silently reverting it produces /// ytLive.exe again — which is why the rename lands before a depot upload rather than /// after (Steamworks: renaming a live exe is painful). /// Assembly-qualified WPF pack URIs (/Assembly;component/path) resolve by that /// same name. A stale /ytLive;component/… compiles, runs, and then fails silently /// the moment that particular view opens — a blank window icon, a missing logo in the overlay /// host. Nobody notices until a dialog is opened at the wrong time, so the rename is exactly the /// kind of change that needs a source-level guard. /// /// /// The C# namespaces stay ytLive: they are not user-visible, and the file churn /// would buy nothing. Only the assembly name and the URIs that quote it move. /// public class AssemblyIdentityTests { private const string ShipName = "LlamaCasty"; private const string LegacyName = "ytLive"; [Fact] public void The_assembly_is_LlamaCasty_and_no_pack_uri_still_names_the_legacy_assembly() { Assert.Equal(ShipName, typeof(MainWindow).Assembly.GetName().Name); var root = RepoRoot(); var stale = Directory.EnumerateFiles(root, "*.xaml", SearchOption.AllDirectories) .Where(path => !IsBuildOutput(path)) .Where(path => File.ReadAllText(path).Contains("/" + LegacyName + ";component/", StringComparison.Ordinal)) .Select(path => Path.GetRelativePath(root, path)) .ToArray(); Assert.True(stale.Length == 0, "These XAML files still point at the legacy assembly name in a pack URI, which " + "fails silently at runtime: " + string.Join(", ", stale)); } /// Walks up from the test output directory to the repo root (the folder holding /// ytLive.csproj). private static string RepoRoot() { var dir = new DirectoryInfo(AppContext.BaseDirectory); while (dir != null) { if (File.Exists(Path.Combine(dir.FullName, "ytLive.csproj"))) return dir.FullName; dir = dir.Parent; } throw new InvalidOperationException("Could not locate the repo root from " + AppContext.BaseDirectory); } /// Publish and compile output carry copies of the XAML (and old generated XAML); /// only the source tree is the thing under test. private static bool IsBuildOutput(string path) { var parts = path.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); return parts.Any(part => part.Equals("bin", StringComparison.OrdinalIgnoreCase) || part.Equals("obj", StringComparison.OrdinalIgnoreCase) || part.Equals("artifacts", StringComparison.OrdinalIgnoreCase)); } }