From 0cbeba6d48f60c396f6e09ddec604238291ea820 Mon Sep 17 00:00:00 2001 From: "pullfrog[bot]" <226033991+pullfrog[bot]@users.noreply.github.com> Date: Fri, 25 Sep 2026 19:25:10 +0000 Subject: [PATCH] test: validate localization placeholders --- tests/ConsoleMode.Tests/LocalizationTests.cs | 34 ++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tests/ConsoleMode.Tests/LocalizationTests.cs b/tests/ConsoleMode.Tests/LocalizationTests.cs index d1aa939..8e2f27f 100644 --- a/tests/ConsoleMode.Tests/LocalizationTests.cs +++ b/tests/ConsoleMode.Tests/LocalizationTests.cs @@ -1,4 +1,5 @@ using System.Text.Json; +using System.Text.RegularExpressions; using ConsoleMode.Models; using ConsoleMode.Services; @@ -6,6 +7,8 @@ namespace ConsoleMode.Tests; public sealed class LocalizationTests { + private static readonly Regex PlaceholderPattern = new(@"\{\d+\}", RegexOptions.Compiled); + [Fact] public void Embedded_catalogs_support_en_us_and_pt_br_with_matching_keys() { @@ -56,6 +59,26 @@ public void Every_xaml_text_property_has_a_key_in_both_catalogs() } } + [Fact] + public void Catalog_placeholders_match_english() + { + var english = LoadCatalog(LocalizationService.EnglishUnitedStates); + foreach (var language in LocalizationService.SupportedLanguages + .Select(l => l.Code) + .Where(code => code != LocalizationService.EnglishUnitedStates)) + { + var localized = LoadCatalog(language); + foreach (var key in english.Keys.Order()) + { + var expected = ExtractPlaceholders(english[key]); + var actual = ExtractPlaceholders(localized[key]); + Assert.True( + expected.SetEquals(actual), + $"{language}:{key} has placeholders {{{string.Join(", ", actual.Order())}}}; expected {{{string.Join(", ", expected.Order())}}}."); + } + } + } + [Fact] public void Display_mode_labels_follow_the_language_switch() { @@ -115,4 +138,15 @@ public void App_language_config_is_empty_until_chosen_and_roundtrips() [InlineData(null, null, null, "en-US")] public void Initial_language_follows_saved_choice_then_installer_then_windows(string? saved, string? installer, string? windows, string expected) => Assert.Equal(expected, LocalizationService.ResolveInitial(saved, installer, windows)); + + private static Dictionary LoadCatalog(string language) + { + var resourceName = $"ConsoleMode.Localization.Strings.{language}.json"; + using var stream = typeof(LocalizationService).Assembly.GetManifestResourceStream(resourceName); + Assert.NotNull(stream); + return JsonSerializer.Deserialize>(stream!)!; + } + + private static HashSet ExtractPlaceholders(string value) => + PlaceholderPattern.Matches(value).Select(match => match.Value).ToHashSet(); }