using System.Text.Json; using ClaudeDo.Localization; namespace ClaudeDo.Localization.Tests; public class EnJsonCoverageTests { private static string LocalesDir() { var dir = AppContext.BaseDirectory; while (dir is not null) { var candidate = Path.Combine(dir, "src", "ClaudeDo.Localization", "locales"); if (Directory.Exists(candidate)) return candidate; dir = Path.GetDirectoryName(dir); } throw new DirectoryNotFoundException("Could not locate src/ClaudeDo.Localization/locales"); } [Fact] public void All_locale_files_parse_as_valid_json() { var localesDir = LocalesDir(); foreach (var path in Directory.EnumerateFiles(localesDir, "*.json")) { try { JsonDocument.Parse(File.ReadAllText(path)); } catch (JsonException ex) { Assert.Fail($"{Path.GetFileName(path)} is not valid JSON: {ex.Message}"); } } } [Fact] public void Every_locale_has_same_keys_as_english() { var localesDir = LocalesDir(); var jsonFileCount = Directory.EnumerateFiles(localesDir, "*.json").Count(); var store = LocaleStore.Load(localesDir); Assert.True(store.Available.Count == jsonFileCount, $"Expected {jsonFileCount} locale(s) to load from {localesDir}, but only {store.Available.Count} loaded " + $"(loaded: {string.Join(", ", store.Available.Select(l => l.Code))}). A *.json file failed to parse."); Assert.True(store.TryGet("de", out _), "Locale 'de' did not load — de.json failed to parse."); Assert.True(store.TryGet("en", out var en)); var enKeys = en!.Strings.Keys.ToHashSet(); foreach (var locale in store.Available) { var keys = locale.Strings.Keys.ToHashSet(); var missing = enKeys.Except(keys).OrderBy(k => k).ToList(); var extra = keys.Except(enKeys).OrderBy(k => k).ToList(); Assert.True(missing.Count == 0, $"Locale '{locale.Code}' missing keys: {string.Join(", ", missing)}"); Assert.True(extra.Count == 0, $"Locale '{locale.Code}' has extra keys not in en.json: {string.Join(", ", extra)}"); } } }