183 lines
7.5 KiB
C#
183 lines
7.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using AibisDream.Framework;
|
|
using AibisDream.EditorTools;
|
|
using AibisDream.UI;
|
|
using NUnit.Framework;
|
|
using TMPro;
|
|
using UnityEditor;
|
|
using UnityEditor.AddressableAssets;
|
|
using UnityEditor.SceneManagement;
|
|
using UnityEngine;
|
|
using UnityEngine.SceneManagement;
|
|
|
|
namespace AibisDream.SystemEditor.Tests
|
|
{
|
|
public sealed class TypographyContractTests
|
|
{
|
|
private const string ProfileFolder = "Assets/GameContent/Common/Typography/Profiles";
|
|
|
|
[TestCase(LocaleKind.Cn, TypographyProfileKind.ZhHans)]
|
|
[TestCase(LocaleKind.Ja, TypographyProfileKind.Japanese)]
|
|
[TestCase(LocaleKind.En, TypographyProfileKind.Latin)]
|
|
[TestCase(LocaleKind.Es, TypographyProfileKind.Latin)]
|
|
[TestCase(LocaleKind.PtBr, TypographyProfileKind.Latin)]
|
|
[TestCase(LocaleKind.Ru, TypographyProfileKind.Russian)]
|
|
public void LocaleMapping_UsesExpectedProfile(LocaleKind locale, TypographyProfileKind expected)
|
|
{
|
|
Assert.That(TypographyLocaleMapping.GetProfileKind(locale), Is.EqualTo(expected));
|
|
Assert.That(
|
|
TypographyLocaleMapping.GetProfileKey(locale),
|
|
Is.EqualTo($"Typography/Profile/{expected}"));
|
|
}
|
|
|
|
[Test]
|
|
public void Resolve_MissingRoleFallsBackToBody()
|
|
{
|
|
TMP_FontAsset font = AssetDatabase.LoadAssetAtPath<TMP_FontAsset>(
|
|
"Assets/Font/Assets/ChillBitmap_16px SDF.asset");
|
|
var profile = ScriptableObject.CreateInstance<TypographyProfile>();
|
|
try
|
|
{
|
|
var body = new TypographyStyle(TypographyRole.Body, font);
|
|
profile.Configure(TypographyProfileKind.Latin, new[] { body });
|
|
Assert.That(profile.Resolve(TypographyRole.Dialogue), Is.SameAs(body));
|
|
}
|
|
finally
|
|
{
|
|
UnityEngine.Object.DestroyImmediate(profile);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void Binding_ReapplyUsesCapturedBaselineWithoutAccumulatingMetrics()
|
|
{
|
|
TMP_FontAsset font = AssetDatabase.LoadAssetAtPath<TMP_FontAsset>(
|
|
"Assets/Font/Assets/ChillBitmap_16px SDF.asset");
|
|
var profile = ScriptableObject.CreateInstance<TypographyProfile>();
|
|
var go = new GameObject("TypographyMetricContract", typeof(RectTransform));
|
|
try
|
|
{
|
|
TextMeshProUGUI text = go.AddComponent<TextMeshProUGUI>();
|
|
text.fontSize = 40f;
|
|
text.lineSpacing = 3f;
|
|
text.characterSpacing = 2f;
|
|
LocalizedTypography binding = go.AddComponent<LocalizedTypography>();
|
|
profile.Configure(
|
|
TypographyProfileKind.Latin,
|
|
new[]
|
|
{
|
|
new TypographyStyle(
|
|
TypographyRole.Body,
|
|
font,
|
|
fontSizeMultiplier: 0.75f,
|
|
lineSpacingOffset: 1f,
|
|
characterSpacingOffset: 2f)
|
|
});
|
|
|
|
binding.ApplyProfile(profile);
|
|
binding.ApplyProfile(profile);
|
|
|
|
Assert.That(text.fontSize, Is.EqualTo(30f));
|
|
Assert.That(text.lineSpacing, Is.EqualTo(4f));
|
|
Assert.That(text.characterSpacing, Is.EqualTo(4f));
|
|
}
|
|
finally
|
|
{
|
|
UnityEngine.Object.DestroyImmediate(go);
|
|
UnityEngine.Object.DestroyImmediate(profile);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void FirstRoundProfiles_AreCompleteAndAddressableByConvention()
|
|
{
|
|
foreach (TypographyProfileKind kind in Enum.GetValues(typeof(TypographyProfileKind)))
|
|
{
|
|
TypographyProfile profile = AssetDatabase.LoadAssetAtPath<TypographyProfile>(
|
|
$"{ProfileFolder}/{kind}.asset");
|
|
Assert.That(profile, Is.Not.Null, kind.ToString());
|
|
Assert.That(profile.ProfileKind, Is.EqualTo(kind));
|
|
Assert.That(profile.GetValidationErrors(), Is.Empty, kind.ToString());
|
|
Assert.That(
|
|
Enum.GetValues(typeof(TypographyRole)).Cast<TypographyRole>()
|
|
.All(role => profile.Resolve(role) != null),
|
|
Is.True,
|
|
kind.ToString());
|
|
|
|
string guid = AssetDatabase.AssetPathToGUID($"{ProfileFolder}/{kind}.asset");
|
|
var entry = AddressableAssetSettingsDefaultObject.Settings.FindAssetEntry(guid);
|
|
Assert.That(entry, Is.Not.Null, kind.ToString());
|
|
Assert.That(entry.address, Is.EqualTo($"Typography/Profile/{kind}"));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TerminalPrefabs_BindEveryTextExactlyOnce()
|
|
{
|
|
foreach (string path in TerminalTypographyMigration.PrefabPaths)
|
|
{
|
|
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);
|
|
Assert.That(prefab, Is.Not.Null, path);
|
|
|
|
TMP_Text[] texts = prefab.GetComponentsInChildren<TMP_Text>(true);
|
|
Assert.That(texts, Is.Not.Empty, path);
|
|
foreach (TMP_Text text in texts)
|
|
{
|
|
LocalizedTypography[] bindings = text.GetComponents<LocalizedTypography>();
|
|
Assert.That(bindings, Has.Length.EqualTo(1), $"{path}: {text.name}");
|
|
Assert.That(bindings[0].Role, Is.EqualTo(TypographyRole.Terminal),
|
|
$"{path}: {text.name}");
|
|
}
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void PersistenceTerminalComposition_InheritsTypographyBindings()
|
|
{
|
|
Scene scene = SceneManager.GetSceneByPath(TerminalTypographyMigration.PersistenceScenePath);
|
|
bool openedForTest = !scene.IsValid() || !scene.isLoaded;
|
|
if (openedForTest)
|
|
{
|
|
scene = EditorSceneManager.OpenScene(
|
|
TerminalTypographyMigration.PersistenceScenePath,
|
|
OpenSceneMode.Additive);
|
|
}
|
|
try
|
|
{
|
|
Component[] hosts = scene.GetRootGameObjects()
|
|
.SelectMany(root => root.GetComponentsInChildren<Component>(true))
|
|
.Where(component => component is TerminalPanel || component is InGameTerminalPanel)
|
|
.ToArray();
|
|
Assert.That(hosts, Has.Length.EqualTo(2));
|
|
|
|
var violations = new List<string>();
|
|
foreach (Component host in hosts)
|
|
{
|
|
foreach (TMP_Text text in host.GetComponentsInChildren<TMP_Text>(true))
|
|
{
|
|
LocalizedTypography[] bindings = text.GetComponents<LocalizedTypography>();
|
|
if (bindings.Length != 1)
|
|
{
|
|
violations.Add($"{host.name}: {text.name} has {bindings.Length} bindings");
|
|
continue;
|
|
}
|
|
|
|
if (bindings[0].Role != TypographyRole.Terminal)
|
|
violations.Add($"{host.name}: {text.name} uses {bindings[0].Role}");
|
|
}
|
|
}
|
|
|
|
Assert.That(violations, Is.Empty, string.Join("\n", violations));
|
|
}
|
|
finally
|
|
{
|
|
if (openedForTest)
|
|
EditorSceneManager.CloseScene(scene, true);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|