using System.Collections; using System.Globalization; using System.IO; using System.Reflection; using System.Resources; using System.Text.RegularExpressions; using CursorLang.Core.Services; namespace CursorLang.Settings.Tests.Views; /// /// The settings window markup against the resource strings. /// /// /// The resources live in Core and the markup lives here, so the check that the two /// agree has to live here too. What the resources say among themselves — that every /// key is translated, that the placeholders match — is checked by StringsTests, next /// to the resources. /// /// The markup is read as an embedded copy rather than off disk: a test that walks up /// the folder tree looking for a .xaml file breaks the moment anything moves. /// public sealed partial class MarkupStringsTests { private static readonly ResourceManager Resources = new("CursorLang.Core.Resources.Strings", typeof(LocalizationService).Assembly); /// /// Every key the settings window markup asks for has to exist in the /// resources: otherwise the user sees the key itself in its place. /// [Fact] public void Every_key_from_the_settings_window_markup_exists_in_the_resources() { HashSet known = [.. NeutralKeys()]; List missing = []; foreach (Match match in LocalizationBinding().Matches(ReadSettingsWindowMarkup())) { string key = match.Groups["key"].Value; if (!known.Contains(key)) { missing.Add(key); } } Assert.Empty(missing); } /// The markup does ask for strings — otherwise the check above means nothing. [Fact] public void The_settings_window_markup_asks_for_resource_strings() { Assert.NotEmpty(LocalizationBinding().Matches(ReadSettingsWindowMarkup())); } private static IEnumerable NeutralKeys() { ResourceSet set = Resources.GetResourceSet(CultureInfo.InvariantCulture, true, true)!; foreach (DictionaryEntry entry in set) { yield return (string)entry.Key; } } private static string ReadSettingsWindowMarkup() { using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MainWindow.xaml") ?? throw new InvalidOperationException("The settings window markup is not embedded in the test assembly"); using var reader = new StreamReader(stream); return reader.ReadToEnd(); } [GeneratedRegex(@"Localization\[(?\w+)\]")] private static partial Regex LocalizationBinding(); }