Complete the retail cast-intent, target, component, enchantment, and busy-state paths; mount the DAT-authored spell bar, spellbook, component book, effects panels, and shared panel lifecycle; and add scoped input plus conformance coverage. Co-Authored-By: Codex <noreply@openai.com>
197 lines
6.6 KiB
C#
197 lines
6.6 KiB
C#
using AcDream.App.UI;
|
|
|
|
namespace AcDream.App.Tests.UI;
|
|
|
|
public class UiItemSlotTests
|
|
{
|
|
[Fact]
|
|
public void IsLeafWidget()
|
|
=> Assert.True(new UiItemSlot().ConsumesDatChildren);
|
|
|
|
[Fact]
|
|
public void DefaultEmptySprite_isToolbarBorder()
|
|
=> Assert.Equal(0x060074CFu, new UiItemSlot().EmptySprite);
|
|
|
|
[Fact]
|
|
public void DefaultWaitingSprite_isRetailGhostMesh()
|
|
=> Assert.Equal(0x0600109Au, new UiItemSlot().WaitingSprite);
|
|
|
|
[Fact]
|
|
public void Empty_whenNoItem()
|
|
{
|
|
var s = new UiItemSlot();
|
|
Assert.Equal(0u, s.ItemId);
|
|
Assert.Equal(0u, s.IconTexture);
|
|
}
|
|
|
|
[Fact]
|
|
public void SetItem_setsIdAndTexture()
|
|
{
|
|
var s = new UiItemSlot();
|
|
s.SetItem(0x5001u, 0x99u);
|
|
Assert.Equal(0x5001u, s.ItemId);
|
|
Assert.Equal(0x99u, s.IconTexture);
|
|
}
|
|
|
|
[Fact]
|
|
public void Clear_afterSetItem_resetsToEmpty()
|
|
{
|
|
var s = new UiItemSlot();
|
|
s.SetItem(0x5001u, 0x99u);
|
|
s.Clear();
|
|
Assert.Equal(0u, s.ItemId);
|
|
Assert.Equal(0u, s.IconTexture);
|
|
}
|
|
|
|
[Fact]
|
|
public void DoubleClick_invokesDoubleClicked()
|
|
{
|
|
var s = new UiItemSlot();
|
|
bool fired = false;
|
|
s.DoubleClicked = () => fired = true;
|
|
|
|
s.OnEvent(new UiEvent(0u, s, UiEventType.DoubleClick));
|
|
|
|
Assert.True(fired);
|
|
}
|
|
|
|
[Fact]
|
|
public void CatalogSlot_keeps_catalog_identity_separate_from_object_guid()
|
|
{
|
|
var slot = new UiCatalogSlot { EntryId = 1234u, CatalogIconTexture = 99u };
|
|
|
|
Assert.Equal(1234u, slot.EntryId);
|
|
Assert.Equal(0u, slot.ItemId);
|
|
Assert.False(slot.IsDragSource);
|
|
Assert.Null(slot.GetDragPayload());
|
|
}
|
|
|
|
// ── Shortcut number tests ────────────────────────────────────────────────
|
|
// Port of UIElement_UIItem::SetShortcutNum (acclient_2013_pseudo_c.txt:229465).
|
|
|
|
[Fact]
|
|
public void ShortcutNum_defaultIsMinusOne()
|
|
{
|
|
var s = new UiItemSlot();
|
|
Assert.Equal(-1, s.ShortcutNum);
|
|
}
|
|
|
|
[Fact]
|
|
public void ShortcutGhosted_defaultsFalse()
|
|
{
|
|
var s = new UiItemSlot();
|
|
Assert.False(s.ShortcutGhosted);
|
|
}
|
|
|
|
[Fact]
|
|
public void SetShortcutNum_setsIndexAndGhostedState()
|
|
{
|
|
var s = new UiItemSlot();
|
|
s.SetShortcutNum(3, ghosted: true);
|
|
Assert.Equal(3, s.ShortcutNum);
|
|
Assert.True(s.ShortcutGhosted);
|
|
}
|
|
|
|
[Fact]
|
|
public void SetShortcutNum_regularState()
|
|
{
|
|
var s = new UiItemSlot();
|
|
s.SetShortcutNum(0, ghosted: false);
|
|
Assert.Equal(0, s.ShortcutNum);
|
|
Assert.False(s.ShortcutGhosted);
|
|
}
|
|
|
|
[Fact]
|
|
public void ClearShortcutNum_setsMinusOne()
|
|
{
|
|
var s = new UiItemSlot();
|
|
s.SetShortcutNum(5, ghosted: false);
|
|
s.ClearShortcutNum();
|
|
Assert.Equal(-1, s.ShortcutNum);
|
|
}
|
|
|
|
// ── ActiveDigitArray occupancy gating (decomp UIElement_UIItem::SetShortcutNum:229481) ──
|
|
|
|
private static readonly uint[] Regular = { 0x10u, 0x11u, 0x12u };
|
|
private static readonly uint[] Ghosted = { 0x20u, 0x21u, 0x22u };
|
|
private static readonly uint[] Empty = { 0x30u, 0x31u, 0x32u };
|
|
|
|
/// <summary>
|
|
/// When ItemId == 0 (empty slot), ActiveDigitArray returns EmptyDigits regardless
|
|
/// of ShortcutGhosted. Retail ref: UIElement_UIItem::SetShortcutNum (decomp 229481) —
|
|
/// else branch when m_elem_Icon->m_state == 0x1000001c (empty).
|
|
/// </summary>
|
|
[Fact]
|
|
public void ActiveDigitArray_emptySlot_returnsEmptyDigits()
|
|
{
|
|
var s = new UiItemSlot { RegularDigits = Regular, GhostedDigits = Ghosted, EmptyDigits = Empty };
|
|
s.SetShortcutNum(0, ghosted: false);
|
|
// ItemId == 0 → EmptyDigits
|
|
Assert.Same(Empty, s.ActiveDigitArray());
|
|
}
|
|
|
|
[Fact]
|
|
public void ActiveDigitArray_emptySlot_ghosted_stillReturnsEmptyDigits()
|
|
{
|
|
var s = new UiItemSlot { RegularDigits = Regular, GhostedDigits = Ghosted, EmptyDigits = Empty };
|
|
s.SetShortcutNum(0, ghosted: true);
|
|
// ItemId == 0 → EmptyDigits regardless of stance
|
|
Assert.Same(Empty, s.ActiveDigitArray());
|
|
}
|
|
|
|
/// <summary>
|
|
/// When ItemId != 0 (occupied), ActiveDigitArray returns RegularDigits or GhostedDigits
|
|
/// depending on ShortcutGhosted. Retail ref: UIElement_UIItem::SetShortcutNum (decomp 229481/229493).
|
|
/// </summary>
|
|
[Fact]
|
|
public void ActiveDigitArray_occupiedSlot_regular_returnsRegularDigits()
|
|
{
|
|
var s = new UiItemSlot { RegularDigits = Regular, GhostedDigits = Ghosted, EmptyDigits = Empty };
|
|
s.SetItem(0x5001u, 0x99u);
|
|
s.SetShortcutNum(0, ghosted: false);
|
|
Assert.Same(Regular, s.ActiveDigitArray());
|
|
}
|
|
|
|
[Fact]
|
|
public void ActiveDigitArray_occupiedSlot_ghosted_returnsGhostedDigits()
|
|
{
|
|
var s = new UiItemSlot { RegularDigits = Regular, GhostedDigits = Ghosted, EmptyDigits = Empty };
|
|
s.SetItem(0x5001u, 0x99u);
|
|
s.SetShortcutNum(0, ghosted: true);
|
|
Assert.Same(Ghosted, s.ActiveDigitArray());
|
|
}
|
|
|
|
[Fact]
|
|
public void ActiveDigitArray_emptySlot_nullEmptyDigits_returnsNull()
|
|
{
|
|
var s = new UiItemSlot { RegularDigits = Regular, GhostedDigits = Ghosted, EmptyDigits = null };
|
|
s.SetShortcutNum(0, ghosted: false);
|
|
Assert.Null(s.ActiveDigitArray());
|
|
}
|
|
|
|
// ── Container-switching indicator overlays (decomp SetOpenContainerState 0x004e1200 /
|
|
// SetSelectedState 0x004e1240) ───────────────────────────────────────────────────────
|
|
[Fact]
|
|
public void Selected_defaultsFalse() => Assert.False(new UiItemSlot().Selected);
|
|
|
|
[Fact]
|
|
public void IsOpenContainer_defaultsFalse() => Assert.False(new UiItemSlot().IsOpenContainer);
|
|
|
|
[Fact]
|
|
public void SelectedSprite_default_isGreenYellowSquare()
|
|
=> Assert.Equal(0x06004D21u, new UiItemSlot().SelectedSprite);
|
|
|
|
[Fact]
|
|
public void OpenContainerSprite_default_isTriangle()
|
|
=> Assert.Equal(0x06005D9Cu, new UiItemSlot().OpenContainerSprite);
|
|
|
|
// ── Container capacity bar (decomp UpdateCapacityDisplay 0x004e16e0, element 0x10000347) ──
|
|
[Fact]
|
|
public void CapacityFill_defaultsHidden() => Assert.Equal(-1f, new UiItemSlot().CapacityFill);
|
|
|
|
[Fact]
|
|
public void CapacityBackSprite_default() => Assert.Equal(0x06004D22u, new UiItemSlot().CapacityBackSprite);
|
|
|
|
[Fact]
|
|
public void CapacityFrontSprite_default() => Assert.Equal(0x06004D23u, new UiItemSlot().CapacityFrontSprite);
|
|
}
|