Covers the pure-logic surface of commit 1:
VitalsVMTests
* HealthPercent reads from CombatState.GetHealthPercent
* safe-default 1.0 when GUID unknown / not yet set / never updated
* SetLocalPlayerGuid reroutes lookup to the new guid (no stale cache)
* StaminaPercent / ManaPercent are null for D.2a scope
* ctor throws ArgumentNullException on null CombatState
PanelContextTests
* record-struct fields round-trip
* value-based equality
NullCommandBusTests
* Publish accepts any record type without throwing
* Instance is a true singleton
csproj template mirrors AcDream.Core.Tests (xUnit 2.9.3, Test.Sdk 17.14.1,
runner 3.1.4, coverlet 6.0.4, implicit Using Xunit). References only
AcDream.UI.Abstractions — no runtime / GL dependency, tests run fast.
80 lines
2.4 KiB
C#
80 lines
2.4 KiB
C#
using AcDream.Core.Combat;
|
|
using AcDream.UI.Abstractions.Panels.Vitals;
|
|
|
|
namespace AcDream.UI.Abstractions.Tests;
|
|
|
|
public sealed class VitalsVMTests
|
|
{
|
|
[Fact]
|
|
public void HealthPercent_ReturnsCombatStateValue_AfterUpdateHealth()
|
|
{
|
|
var combat = new CombatState();
|
|
uint guid = 0x5000_0042u;
|
|
combat.OnUpdateHealth(guid, 0.42f);
|
|
|
|
var vm = new VitalsVM(combat);
|
|
vm.SetLocalPlayerGuid(guid);
|
|
|
|
Assert.Equal(0.42f, vm.HealthPercent, precision: 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void HealthPercent_ReturnsOne_WhenGuidUnknown()
|
|
{
|
|
var combat = new CombatState();
|
|
var vm = new VitalsVM(combat);
|
|
|
|
// No SetLocalPlayerGuid call — defaults to 0 which CombatState has never seen.
|
|
Assert.Equal(1f, vm.HealthPercent);
|
|
}
|
|
|
|
[Fact]
|
|
public void HealthPercent_ReturnsOne_WhenGuidSetButNeverUpdated()
|
|
{
|
|
var combat = new CombatState();
|
|
var vm = new VitalsVM(combat);
|
|
vm.SetLocalPlayerGuid(0xDEAD_BEEFu);
|
|
|
|
Assert.Equal(1f, vm.HealthPercent);
|
|
}
|
|
|
|
[Fact]
|
|
public void StaminaPercent_IsNull_ForD2aScope()
|
|
{
|
|
// D.2a explicitly defers Stamina until LocalPlayerState + PlayerDescription
|
|
// wiring. When that arrives VitalsVM.StaminaPercent becomes non-null and
|
|
// VitalsPanel starts drawing the Stam bar automatically.
|
|
var vm = new VitalsVM(new CombatState());
|
|
Assert.Null(vm.StaminaPercent);
|
|
}
|
|
|
|
[Fact]
|
|
public void ManaPercent_IsNull_ForD2aScope()
|
|
{
|
|
var vm = new VitalsVM(new CombatState());
|
|
Assert.Null(vm.ManaPercent);
|
|
}
|
|
|
|
[Fact]
|
|
public void SetLocalPlayerGuid_ReroutesHealthLookup_WithoutStaleCache()
|
|
{
|
|
// Simulate the realistic GameWindow flow: VM is constructed pre-login
|
|
// with GUID=0, then SetLocalPlayerGuid is called at EnterWorld.
|
|
var combat = new CombatState();
|
|
uint playerGuid = 0x5003_E219u;
|
|
combat.OnUpdateHealth(playerGuid, 0.75f);
|
|
|
|
var vm = new VitalsVM(combat);
|
|
// Before SetLocalPlayerGuid — reads GUID=0 → returns safe 1.0.
|
|
Assert.Equal(1f, vm.HealthPercent);
|
|
|
|
vm.SetLocalPlayerGuid(playerGuid);
|
|
Assert.Equal(0.75f, vm.HealthPercent, precision: 3);
|
|
}
|
|
|
|
[Fact]
|
|
public void Constructor_ThrowsOnNullCombat()
|
|
{
|
|
Assert.Throws<ArgumentNullException>(() => new VitalsVM(null!));
|
|
}
|
|
}
|