using System.Text.RegularExpressions; using Material.Icons; namespace ClaudeDo.Ui.Tests; /// Guards every mdi:Name literal in the Ui sources: an unknown kind makes IconKeyConverter return null and the icon silently vanishes. public class MdiIconNamesTests { /// mdi:Name in XAML/C# plus MdiGeometry("Name") (MarkdownView prefixes the key itself). private static readonly Regex NamePattern = new(@"mdi:(\w+)|MdiGeometry\(""(\w+)""\)", RegexOptions.Compiled); [Fact] public void EveryMdiNameInUiSources_IsAMaterialIconKind() { var uiDir = Path.Combine(FindRepoRoot(), "src", "ClaudeDo.Ui"); var files = Directory.EnumerateFiles(uiDir, "*.*", SearchOption.AllDirectories) .Where(f => (f.EndsWith(".axaml") || f.EndsWith(".cs")) && !f.Contains($"{Path.DirectorySeparatorChar}obj{Path.DirectorySeparatorChar}") && !f.Contains($"{Path.DirectorySeparatorChar}bin{Path.DirectorySeparatorChar}")); var unknown = new List(); var seen = 0; foreach (var file in files) foreach (Match m in NamePattern.Matches(File.ReadAllText(file))) { seen++; var name = m.Groups[1].Success ? m.Groups[1].Value : m.Groups[2].Value; if (!Enum.TryParse(name, out _)) unknown.Add($"{Path.GetRelativePath(uiDir, file)}: {name}"); } Assert.True(seen > 0, "scan found no mdi: names — the pattern or the repo-root lookup is broken"); Assert.True(unknown.Count == 0, "Unknown MaterialIconKind names:\n" + string.Join('\n', unknown)); } private static string FindRepoRoot() { var dir = new DirectoryInfo(AppContext.BaseDirectory); while (dir is not null && !File.Exists(Path.Combine(dir.FullName, "ClaudeDo.slnx"))) dir = dir.Parent; return dir?.FullName ?? throw new InvalidOperationException("ClaudeDo.slnx not found above " + AppContext.BaseDirectory); } }