Files
unity/Assets/Tests/EditMode/LocalizationTests.cs
T

134 lines
6.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using NUnit.Framework;
using UnityEditor;
using UnityEngine;
namespace Ironspore.Tests
{
public sealed class LocalizationTests
{
LocalizationCatalog catalog;
bool hadPreference;
string preference;
[SetUp]
public void Setup()
{
hadPreference = PlayerPrefs.HasKey(GameLocalization.PreferenceKey);
preference = PlayerPrefs.GetString(GameLocalization.PreferenceKey, "");
catalog = AssetDatabase.LoadAssetAtPath<LocalizationCatalog>("Assets/Game/Localization/LocalizationCatalog.asset");
Assert.IsNotNull(catalog, "Run Ironspore/Configure Localization first.");
GameLocalization.Initialize(catalog);
}
[TearDown]
public void Cleanup()
{
if (hadPreference)
PlayerPrefs.SetString(GameLocalization.PreferenceKey, preference);
else
PlayerPrefs.DeleteKey(GameLocalization.PreferenceKey);
if (catalog)
GameLocalization.Initialize(catalog);
PlayerPrefs.Save();
}
[TestCase("en", "zh-CN", "en")]
[TestCase("zh-Hans", "en-US", "zh-Hans")]
[TestCase("", "zh-TW", "zh-Hans")]
[TestCase("", "en-GB", "en")]
[TestCase("obsolete", "zh-HK", "zh-Hans")]
[TestCase("", "ja-JP", "en")]
[TestCase(null, null, "en")]
public void SavedSystemAndFallbackPriority(string saved, string system, string expected)
{
Assert.AreEqual(expected, GameLocalization.ResolveInitialLocale(saved, system));
}
[Test]
public void AdditionalLocalesCanUseTheSameSelector()
{
Assert.AreEqual("fr", GameLocalization.ResolveInitialLocale("fr", "en-US", new[] { "en", "zh-Hans", "fr" }));
Assert.AreEqual("fr", GameLocalization.ResolveInitialLocale("", "fr-CA", new[] { "en", "fr" }));
}
[Test]
public void EveryKeyAndFormatArgumentMatchesAndRequiredGlyphsExist()
{
var english = GameLocalization.ReadTable(catalog.locales.Single(x => x.code == "en").table);
foreach (var locale in catalog.locales)
{
var translated = GameLocalization.ReadTable(locale.table);
CollectionAssert.AreEquivalent(english.Keys, translated.Keys, locale.code);
foreach (var entry in translated)
{
var pattern = @"\{(\d+)(?:[^}]*)\}";
string[] expected = Regex.Matches(english[entry.Key], pattern).Cast<Match>().Select(x => x.Groups[1].Value).ToArray();
string[] actual = Regex.Matches(entry.Value, pattern).Cast<Match>().Select(x => x.Groups[1].Value).ToArray();
CollectionAssert.AreEquivalent(expected, actual, locale.code + ":" + entry.Key);
int count = expected.Length == 0 ? 0 : expected.Select(int.Parse).Max() + 1;
Assert.DoesNotThrow(() => string.Format(entry.Value, Enumerable.Repeat<object>("sample", count).ToArray()), entry.Key);
foreach (char character in entry.Value.Where(c => !char.IsControl(c)))
Assert.IsTrue(catalog.uiFont.HasCharacter(character), "Missing glyph: " + character + " in " + entry.Key);
}
}
}
[Test]
public void SelectionPersistsAndInvalidSelectionDoesNotChangePreference()
{
Assert.IsTrue(GameLocalization.SelectLocale("zh-Hans"));
GameLocalization.Initialize(catalog);
Assert.AreEqual("zh-Hans", GameLocalization.CurrentCode);
Assert.IsFalse(GameLocalization.SelectLocale("unavailable"));
Assert.AreEqual("zh-Hans", PlayerPrefs.GetString(GameLocalization.PreferenceKey));
Assert.IsTrue(GameLocalization.SelectLocale("en"));
GameLocalization.Initialize(catalog);
Assert.AreEqual("en", GameLocalization.CurrentCode);
}
[Test]
public void ExistingMessagesAndNamesReformatWithoutMutatingSaveOrIdentifiers()
{
var state = new GameSave();
state.run.cargo.Add(new CargoStack("blueprint_coil_capacitor", 1));
string before = JsonUtility.ToJson(state);
var notice = GameLocalization.Message("notice.recovered", GameLocalization.Message("item.blueprint_coil_capacitor"), 3);
GameLocalization.SelectLocale("en", false);
StringAssert.Contains("COIL CAPACITOR", notice.ToString());
GameLocalization.SelectLocale("zh-Hans", false);
StringAssert.Contains("电磁电容", notice.ToString());
StringAssert.Contains("×3", notice.ToString());
StringAssert.Contains("电磁电容", state.run.cargo[0].Name);
Assert.AreEqual(before, JsonUtility.ToJson(state));
Assert.AreEqual(GameSave.CurrentVersion, state.version);
}
[Test]
public void MissingTranslationUsesEnglishFallback()
{
var temporary = ScriptableObject.CreateInstance<LocalizationCatalog>();
var english = new UnityEngine.TextAsset("{\"entries\":[{\"key\":\"test.fallback\",\"value\":\"Readable English {0}\"}]}");
var chinese = new UnityEngine.TextAsset("{\"entries\":[]}");
try
{
temporary.locales = new[] { new GameLocale { code = "en", table = english }, new GameLocale { code = "zh-Hans", table = chinese } };
GameLocalization.Initialize(temporary);
GameLocalization.SelectLocale("zh-Hans", false);
Assert.AreEqual("Readable English 7", GameLocalization.Text("test.fallback", 7));
}
finally
{
UnityEngine.Object.DestroyImmediate(temporary);
UnityEngine.Object.DestroyImmediate(english);
UnityEngine.Object.DestroyImmediate(chinese);
}
}
[Test]
public void DuplicateKeysAreRejected()
{
var table = new UnityEngine.TextAsset("{\"entries\":[{\"key\":\"same\",\"value\":\"one\"},{\"key\":\"same\",\"value\":\"two\"}]}");
try
{
Assert.Throws<ArgumentException>(() => GameLocalization.ReadTable(table));
}
finally { UnityEngine.Object.DestroyImmediate(table); }
}
}
}