134 lines
6.4 KiB
C#
134 lines
6.4 KiB
C#
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); }
|
||
}
|
||
}
|
||
}
|