using Xunit; namespace MrGameEng.Mods.Tests; public sealed class LanguageManagerTests : IDisposable { private readonly string _root = Directory.CreateTempSubdirectory("mrge-lang-tests-").FullName; private int _modCounter; public void Dispose() => Directory.Delete(_root, recursive: true); private Mod WriteLanguageMod(string code, string fileName, string json) { var id = $"mod{_modCounter++:D2}"; var modDir = Path.Combine(_root, id); var languageDir = Path.Combine(modDir, "Languages", code); Directory.CreateDirectory(languageDir); File.WriteAllText(Path.Combine(languageDir, fileName), json); return new Mod(new ModInfo { Id = id }, modDir); } [Fact] public void Get_UsesCurrentLanguage_FallsBackToDefault_ThenKey() { var mod = WriteLanguageMod( "en", "ui.json", """{ "hud.title": "Title", "hud.only-en": "English only" }""" ); var ruDir = Path.Combine(mod.RootPath, "Languages", "ru"); Directory.CreateDirectory(ruDir); File.WriteAllText(Path.Combine(ruDir, "ui.json"), """{ "hud.title": "Заголовок" }"""); var languages = new LanguageManager(defaultLanguage: "en"); languages.Load([mod]); Assert.True(languages.SetLanguage("ru")); Assert.Equal("Заголовок", languages.Get("hud.title")); Assert.Equal("English only", languages.Get("hud.only-en")); // fallback на en Assert.Equal("hud.missing", languages.Get("hud.missing")); // ключ виден, не краш } [Fact] public void Load_LaterMod_OverridesKey() { var core = WriteLanguageMod( "en", "ui.json", """{ "hud.title": "Core", "hud.other": "Other" }""" ); var patch = WriteLanguageMod("en", "ui.json", """{ "hud.title": "Patched" }"""); var languages = new LanguageManager(); languages.Load([core, patch]); Assert.Equal("Patched", languages.Get("hud.title")); Assert.Equal("Other", languages.Get("hud.other")); } [Fact] public void SetLanguage_UnknownCode_ReturnsFalse_AndKeepsCurrent() { var languages = new LanguageManager(); languages.Load([WriteLanguageMod("en", "ui.json", """{ "k": "v" }""")]); Assert.False(languages.SetLanguage("fr")); Assert.Equal("en", languages.CurrentLanguage); Assert.Equal(["en"], languages.AvailableLanguages); } [Fact] public void Format_SubstitutesArguments() { var languages = new LanguageManager(); languages.Load([WriteLanguageMod("en", "ui.json", """{ "hud.pop": "population {0}" }""")]); Assert.Equal("population 80", languages.Format("hud.pop", 80)); } [Fact] public void Load_NonStringValue_Throws() { var mod = WriteLanguageMod("en", "ui.json", """{ "bad": { "nested": true } }"""); var languages = new LanguageManager(); Assert.Throws(() => languages.Load([mod])); } [Fact] public void Revision_Bumps_OnLoadAndLanguageSwitch() { var languages = new LanguageManager(); var before = languages.Revision; languages.Load([WriteLanguageMod("ru", "ui.json", """{ "k": "v" }""")]); Assert.NotEqual(before, languages.Revision); before = languages.Revision; languages.SetLanguage("ru"); Assert.NotEqual(before, languages.Revision); } }