358 lines
16 KiB
C#
358 lines
16 KiB
C#
using NUnit.Framework;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using XGame;
|
|
#if UNITY_EDITOR
|
|
using XGame.EditorTools;
|
|
#endif
|
|
|
|
public sealed class PlayerProfileModuleTests
|
|
{
|
|
[TearDown]
|
|
public void TearDown()
|
|
{
|
|
PlayerProfileStore.ResetToDefault();
|
|
}
|
|
|
|
[Test]
|
|
public void DefaultProfile_HasPlayableCombatStats()
|
|
{
|
|
PlayerProfileData profile = PlayerProfileData.CreateDefault();
|
|
|
|
Assert.That(profile.Nickname, Is.EqualTo("Player"));
|
|
Assert.That(profile.Uid, Is.EqualTo("0"));
|
|
Assert.That(profile.Lv, Is.EqualTo(1));
|
|
Assert.That(profile.HpMax, Is.GreaterThan(0));
|
|
Assert.That(profile.Hp, Is.EqualTo(profile.HpMax));
|
|
Assert.That(profile.MpMax, Is.GreaterThan(0));
|
|
Assert.That(profile.Mp, Is.EqualTo(profile.MpMax));
|
|
Assert.That(profile.Ad, Is.GreaterThan(0));
|
|
Assert.That(profile.MoveSpeed, Is.GreaterThan(0f));
|
|
}
|
|
|
|
[Test]
|
|
public void Replace_SanitizesInvalidValuesAndRaisesChanged()
|
|
{
|
|
int changed = 0;
|
|
Action<PlayerProfileData> handler = _ => changed++;
|
|
PlayerProfileStore.Changed += handler;
|
|
|
|
try
|
|
{
|
|
PlayerProfileStore.Replace(new PlayerProfileData
|
|
{
|
|
Nickname = "Alice",
|
|
Uid = "42",
|
|
AvatarId = -1,
|
|
RoleType = PlayerRoleType.Mage,
|
|
Lv = -5,
|
|
Exp = -20,
|
|
Hp = 999,
|
|
HpMax = 100,
|
|
Mp = -3,
|
|
MpMax = 50,
|
|
AtkSpeed = -1f,
|
|
MoveSpeed = -2f
|
|
});
|
|
}
|
|
finally
|
|
{
|
|
PlayerProfileStore.Changed -= handler;
|
|
}
|
|
|
|
PlayerProfileData current = PlayerProfileStore.Current;
|
|
Assert.That(changed, Is.EqualTo(1));
|
|
Assert.That(current.AvatarId, Is.EqualTo(0));
|
|
Assert.That(current.Lv, Is.EqualTo(1));
|
|
Assert.That(current.Exp, Is.EqualTo(0));
|
|
Assert.That(current.Hp, Is.EqualTo(100));
|
|
Assert.That(current.Mp, Is.EqualTo(0));
|
|
Assert.That(current.AtkSpeed, Is.GreaterThan(0f));
|
|
Assert.That(current.MoveSpeed, Is.GreaterThan(0f));
|
|
}
|
|
|
|
[Test]
|
|
public void Experience01_ClampsAgainstLevelRequirement()
|
|
{
|
|
PlayerProfileData profile = PlayerProfileData.CreateDefault();
|
|
profile.Lv = 2;
|
|
profile.Exp = 150;
|
|
|
|
Assert.That(profile.Experience01, Is.EqualTo(0.75f).Within(0.001f));
|
|
|
|
profile.Exp = 999;
|
|
Assert.That(profile.Experience01, Is.EqualTo(1f));
|
|
}
|
|
|
|
[Test]
|
|
public void AvatarCatalog_NormalizesLegacyAndInvalidIdsToDefault()
|
|
{
|
|
Assert.That(PlayerAvatarCatalog.NormalizeId(0), Is.EqualTo(PlayerAvatarCatalog.DefaultAvatarId));
|
|
Assert.That(PlayerAvatarCatalog.NormalizeId(-3), Is.EqualTo(PlayerAvatarCatalog.DefaultAvatarId));
|
|
Assert.That(PlayerAvatarCatalog.NormalizeId(PlayerAvatarCatalog.Count + 1), Is.EqualTo(PlayerAvatarCatalog.DefaultAvatarId));
|
|
}
|
|
|
|
[Test]
|
|
public void AvatarCatalog_MapsIdsToTwoDigitGamerPicPaths()
|
|
{
|
|
Assert.That(PlayerAvatarCatalog.GetAssetPath(1), Is.EqualTo("Assets/Game/Art/UI/Texture/Icon/GamerPic/GamerPic_01.png"));
|
|
Assert.That(PlayerAvatarCatalog.GetAssetPath(9), Is.EqualTo("Assets/Game/Art/UI/Texture/Icon/GamerPic/GamerPic_09.png"));
|
|
Assert.That(PlayerAvatarCatalog.GetAssetPath(54), Is.EqualTo("Assets/Game/Art/UI/Texture/Icon/GamerPic/GamerPic_54.png"));
|
|
Assert.That(PlayerAvatarCatalog.GetAssetPath(0), Is.EqualTo(PlayerAvatarCatalog.GetAssetPath(PlayerAvatarCatalog.DefaultAvatarId)));
|
|
}
|
|
|
|
[Test]
|
|
public void AvatarPickerJson_DeclaresAllAvatarButtons()
|
|
{
|
|
string projectRoot = System.IO.Directory.GetParent(Application.dataPath).Parent.FullName;
|
|
string jsonPath = System.IO.Path.Combine(projectRoot, "Doc/UIPrefabCreater/UI_PlayerAvatarPicker.json");
|
|
string json = System.IO.File.ReadAllText(jsonPath);
|
|
|
|
for (int avatarId = 1; avatarId <= PlayerAvatarCatalog.Count; avatarId++)
|
|
{
|
|
string suffix = avatarId.ToString("00", System.Globalization.CultureInfo.InvariantCulture);
|
|
StringAssert.Contains("Btn_Avatar_" + suffix, json);
|
|
StringAssert.Contains("GamerPic_" + suffix + ".png", json);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void ConfirmedAvatarUpdate_ChangesOnlyAvatarId()
|
|
{
|
|
PlayerProfileData original = PlayerProfileData.CreateDefault();
|
|
original.Nickname = "Alice";
|
|
original.Gold = 123;
|
|
original.AvatarId = 1;
|
|
PlayerProfileStore.Replace(original);
|
|
|
|
PlayerProfileStore.Update(profile => profile.AvatarId = 17);
|
|
|
|
PlayerProfileData current = PlayerProfileStore.Current;
|
|
Assert.That(current.AvatarId, Is.EqualTo(17));
|
|
Assert.That(current.Nickname, Is.EqualTo("Alice"));
|
|
Assert.That(current.Gold, Is.EqualTo(123));
|
|
}
|
|
|
|
[Test]
|
|
public void ConfirmAvatarPicker_CachesSelectedPickerSpriteForProfileRefresh()
|
|
{
|
|
GameObject moduleObject = new GameObject("PlayerProfileModuleTest");
|
|
GameObject imageObject = new GameObject("SelectedAvatar");
|
|
PlayerProfileModule module = moduleObject.AddComponent<PlayerProfileModule>();
|
|
Image selectedImage = imageObject.AddComponent<Image>();
|
|
Texture2D texture = new Texture2D(1, 1);
|
|
Sprite selectedSprite = Sprite.Create(texture, new Rect(0, 0, 1, 1), new Vector2(0.5f, 0.5f));
|
|
selectedImage.sprite = selectedSprite;
|
|
|
|
try
|
|
{
|
|
FieldInfo pendingAvatarId = typeof(PlayerProfileModule).GetField("pendingAvatarId", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
FieldInfo pickerImages = typeof(PlayerProfileModule).GetField("avatarPickerAvatarImages", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
MethodInfo confirm = typeof(PlayerProfileModule).GetMethod("ConfirmAvatarPicker", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
|
|
pendingAvatarId.SetValue(module, 8);
|
|
Dictionary<int, Image> images = (Dictionary<int, Image>)pickerImages.GetValue(module);
|
|
images[8] = selectedImage;
|
|
confirm.Invoke(module, null);
|
|
|
|
FieldInfo spriteCache = typeof(PlayerProfileModule).GetField("avatarSpriteCache", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
Dictionary<int, Sprite> cache = (Dictionary<int, Sprite>)spriteCache.GetValue(module);
|
|
Assert.That(PlayerProfileStore.Current.AvatarId, Is.EqualTo(8));
|
|
Assert.That(cache[8], Is.SameAs(selectedSprite));
|
|
}
|
|
finally
|
|
{
|
|
UnityEngine.Object.DestroyImmediate(selectedSprite);
|
|
UnityEngine.Object.DestroyImmediate(texture);
|
|
UnityEngine.Object.DestroyImmediate(imageObject);
|
|
UnityEngine.Object.DestroyImmediate(moduleObject);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void CacheAvatarPickerControls_CachesAvatarSpritesFromPickerImages()
|
|
{
|
|
GameObject moduleObject = new GameObject("PlayerProfileModuleTest");
|
|
GameObject pickerRoot = new GameObject("AvatarPicker");
|
|
GameObject avatarObject = new GameObject("Img_Avatar_08");
|
|
PlayerProfileModule module = moduleObject.AddComponent<PlayerProfileModule>();
|
|
Image avatarImage = avatarObject.AddComponent<Image>();
|
|
Texture2D texture = new Texture2D(1, 1);
|
|
Sprite avatarSprite = Sprite.Create(texture, new Rect(0, 0, 1, 1), new Vector2(0.5f, 0.5f));
|
|
avatarImage.sprite = avatarSprite;
|
|
avatarObject.transform.SetParent(pickerRoot.transform, false);
|
|
|
|
try
|
|
{
|
|
FieldInfo pickerView = typeof(PlayerProfileModule).GetField("avatarPickerView", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
MethodInfo cacheControls = typeof(PlayerProfileModule).GetMethod("CacheAvatarPickerControls", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
FieldInfo spriteCache = typeof(PlayerProfileModule).GetField("avatarSpriteCache", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
|
|
pickerView.SetValue(module, pickerRoot);
|
|
cacheControls.Invoke(module, null);
|
|
|
|
Dictionary<int, Sprite> cache = (Dictionary<int, Sprite>)spriteCache.GetValue(module);
|
|
Assert.That(cache[8], Is.SameAs(avatarSprite));
|
|
}
|
|
finally
|
|
{
|
|
UnityEngine.Object.DestroyImmediate(avatarSprite);
|
|
UnityEngine.Object.DestroyImmediate(texture);
|
|
UnityEngine.Object.DestroyImmediate(pickerRoot);
|
|
UnityEngine.Object.DestroyImmediate(moduleObject);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void CacheAvatarPickerControls_MovesSelectedStateAboveAvatarFrame()
|
|
{
|
|
GameObject moduleObject = new GameObject("PlayerProfileModuleTest");
|
|
GameObject pickerRoot = new GameObject("AvatarPicker");
|
|
GameObject slot = new GameObject("AvatarSlot_08");
|
|
GameObject button = new GameObject("Btn_Avatar_08");
|
|
GameObject avatar = new GameObject("Img_Avatar_08");
|
|
GameObject selected = new GameObject("Img_Selected_08");
|
|
PlayerProfileModule module = moduleObject.AddComponent<PlayerProfileModule>();
|
|
|
|
slot.transform.SetParent(pickerRoot.transform, false);
|
|
button.transform.SetParent(slot.transform, false);
|
|
avatar.transform.SetParent(slot.transform, false);
|
|
selected.transform.SetParent(slot.transform, false);
|
|
|
|
try
|
|
{
|
|
FieldInfo pickerView = typeof(PlayerProfileModule).GetField("avatarPickerView", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
MethodInfo cacheControls = typeof(PlayerProfileModule).GetMethod("CacheAvatarPickerControls", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
|
|
Assert.That(selected.transform.GetSiblingIndex(), Is.GreaterThan(button.transform.GetSiblingIndex()));
|
|
|
|
pickerView.SetValue(module, pickerRoot);
|
|
cacheControls.Invoke(module, null);
|
|
|
|
Assert.That(selected.transform.GetSiblingIndex(), Is.GreaterThan(button.transform.GetSiblingIndex()));
|
|
Assert.That(selected.transform.GetSiblingIndex(), Is.GreaterThan(avatar.transform.GetSiblingIndex()));
|
|
}
|
|
finally
|
|
{
|
|
UnityEngine.Object.DestroyImmediate(pickerRoot);
|
|
UnityEngine.Object.DestroyImmediate(moduleObject);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void CacheAvatarPickerControls_MovesPreviewAvatarBehindPreviewFrame()
|
|
{
|
|
GameObject moduleObject = new GameObject("PlayerProfileModuleTest");
|
|
GameObject pickerRoot = new GameObject("AvatarPicker", typeof(RectTransform));
|
|
GameObject previewPanel = new GameObject("Panel_Preview", typeof(RectTransform));
|
|
GameObject previewFrame = new GameObject("Img_PreviewFrame", typeof(RectTransform));
|
|
GameObject previewAvatar = new GameObject("Img_PreviewAvatar", typeof(RectTransform));
|
|
PlayerProfileModule module = moduleObject.AddComponent<PlayerProfileModule>();
|
|
RectTransform previewFrameRect = previewFrame.GetComponent<RectTransform>();
|
|
RectTransform previewAvatarRect = previewAvatar.GetComponent<RectTransform>();
|
|
|
|
previewPanel.transform.SetParent(pickerRoot.transform, false);
|
|
previewFrame.transform.SetParent(previewPanel.transform, false);
|
|
previewAvatar.transform.SetParent(previewFrame.transform, false);
|
|
previewAvatar.AddComponent<Image>();
|
|
previewFrameRect.sizeDelta = new Vector2(112f, 112f);
|
|
previewAvatarRect.sizeDelta = new Vector2(92f, 92f);
|
|
|
|
try
|
|
{
|
|
FieldInfo pickerView = typeof(PlayerProfileModule).GetField("avatarPickerView", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
MethodInfo cacheControls = typeof(PlayerProfileModule).GetMethod("CacheAvatarPickerControls", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
|
|
pickerView.SetValue(module, pickerRoot);
|
|
cacheControls.Invoke(module, null);
|
|
|
|
Assert.That(previewAvatar.transform.parent, Is.EqualTo(previewPanel.transform));
|
|
Assert.That(previewAvatar.transform.GetSiblingIndex(), Is.LessThan(previewFrame.transform.GetSiblingIndex()));
|
|
Assert.That(previewAvatarRect.sizeDelta.x, Is.LessThanOrEqualTo(65f));
|
|
Assert.That(previewAvatarRect.sizeDelta.y, Is.LessThanOrEqualTo(65f));
|
|
}
|
|
finally
|
|
{
|
|
UnityEngine.Object.DestroyImmediate(pickerRoot);
|
|
UnityEngine.Object.DestroyImmediate(moduleObject);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void CacheHudControls_MovesAvatarIconBehindAvatarFrame()
|
|
{
|
|
GameObject moduleObject = new GameObject("PlayerProfileModuleTest");
|
|
GameObject hudRoot = new GameObject("HudRoot");
|
|
GameObject profileButton = new GameObject("Btn_Profile");
|
|
GameObject avatarFrame = new GameObject("Img_AvatarFrame");
|
|
GameObject avatarIcon = new GameObject("Img_AvatarIcon");
|
|
PlayerProfileModule module = moduleObject.AddComponent<PlayerProfileModule>();
|
|
|
|
profileButton.transform.SetParent(hudRoot.transform, false);
|
|
avatarFrame.transform.SetParent(profileButton.transform, false);
|
|
avatarIcon.transform.SetParent(avatarFrame.transform, false);
|
|
avatarIcon.AddComponent<Image>();
|
|
|
|
try
|
|
{
|
|
FieldInfo hudView = typeof(PlayerProfileModule).GetField("hudView", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
MethodInfo cacheControls = typeof(PlayerProfileModule).GetMethod("CacheHudControls", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
|
|
hudView.SetValue(module, hudRoot);
|
|
cacheControls.Invoke(module, null);
|
|
|
|
Assert.That(avatarIcon.transform.parent, Is.EqualTo(profileButton.transform));
|
|
Assert.That(avatarIcon.transform.GetSiblingIndex(), Is.LessThan(avatarFrame.transform.GetSiblingIndex()));
|
|
}
|
|
finally
|
|
{
|
|
UnityEngine.Object.DestroyImmediate(hudRoot);
|
|
UnityEngine.Object.DestroyImmediate(moduleObject);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void ArrangeAvatarIconBehindFrame_MovesDetailAvatarIconBehindAvatarFrame()
|
|
{
|
|
GameObject moduleObject = new GameObject("PlayerProfileModuleTest");
|
|
GameObject panelRoot = new GameObject("PanelRoot");
|
|
GameObject identityPanel = new GameObject("Panel_Identity");
|
|
GameObject avatarFrame = new GameObject("Img_AvatarFrame");
|
|
GameObject avatarIcon = new GameObject("Img_AvatarIcon");
|
|
PlayerProfileModule module = moduleObject.AddComponent<PlayerProfileModule>();
|
|
|
|
identityPanel.transform.SetParent(panelRoot.transform, false);
|
|
avatarFrame.transform.SetParent(identityPanel.transform, false);
|
|
avatarIcon.transform.SetParent(avatarFrame.transform, false);
|
|
avatarIcon.AddComponent<Image>();
|
|
|
|
try
|
|
{
|
|
MethodInfo arrangeAvatarIcon = typeof(PlayerProfileModule).GetMethod("ArrangeAvatarIconBehindFrame", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
|
|
arrangeAvatarIcon.Invoke(module, new object[] { panelRoot });
|
|
|
|
Assert.That(avatarIcon.transform.parent, Is.EqualTo(identityPanel.transform));
|
|
Assert.That(avatarIcon.transform.GetSiblingIndex(), Is.LessThan(avatarFrame.transform.GetSiblingIndex()));
|
|
}
|
|
finally
|
|
{
|
|
UnityEngine.Object.DestroyImmediate(panelRoot);
|
|
UnityEngine.Object.DestroyImmediate(moduleObject);
|
|
}
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
[Test]
|
|
public void PlayerProfileJsonFiles_PassPrefabBuilderValidation()
|
|
{
|
|
Assert.That(JsonUIPrefabBuilder.Validate("../Doc/UIPrefabCreater/UI_PlayerProfileHud.json").Ok, Is.True);
|
|
Assert.That(JsonUIPrefabBuilder.Validate("../Doc/UIPrefabCreater/UI_PlayerProfilePanel.json").Ok, Is.True);
|
|
Assert.That(JsonUIPrefabBuilder.Validate("../Doc/UIPrefabCreater/UI_PlayerAvatarPicker.json").Ok, Is.True);
|
|
}
|
|
#endif
|
|
}
|