using System.Reflection; using System.Resources; using System.Text.RegularExpressions; using AvParser.UI.Localization; namespace AvParser.UI.Tests; /// /// Every key the XAML asks for must actually exist. /// /// /// The parity test compares the two resource files against each other, so a key missing from /// both passes it happily and then renders as !Some.Key! in the running app. That /// happened during a rename: the XAML was repointed at new key names and the keys themselves were /// never added. Only a screenshot caught it, which is too late and too manual. /// public sealed partial class LocalizationCoverageTests { [GeneratedRegex(@"\{l:Loc\s+([A-Za-z0-9_.\-]+)\s*\}", RegexOptions.Compiled)] private static partial Regex LocMarkup(); private static readonly ResourceManager Resources = new( "AvParser.UI.Localization.Strings", typeof(Localizer).GetTypeInfo().Assembly ); /// Walks up to the repository root, which the test binary sits several levels below. private static DirectoryInfo RepositoryRoot() { var directory = new DirectoryInfo(AppContext.BaseDirectory); while (directory is not null && !File.Exists(Path.Combine(directory.FullName, "AvParser.slnx"))) { directory = directory.Parent; } return directory ?? throw new InvalidOperationException("Could not find the repository root."); } [Fact] public void Every_key_used_in_xaml_exists() { var views = Path.Combine(RepositoryRoot().FullName, "src", "AvParser.UI"); var files = Directory.GetFiles(views, "*.axaml", SearchOption.AllDirectories); files.ShouldNotBeEmpty(); var missing = new SortedSet(StringComparer.Ordinal); foreach (var file in files) { foreach (Match match in LocMarkup().Matches(File.ReadAllText(file))) { var key = match.Groups[1].Value; if (Resources.GetString(key, Localizer.Instance.Culture) is null) { missing.Add($"{key} ({Path.GetFileName(file)})"); } } } missing.ShouldBeEmpty(); } }