test(D.5.2): lock effects-clears-to-zero contract (final-review polish)

The 'item with mana vs out of mana' core promise: a draining item whose
UiEffects clears to 0 returns to its base icon. Guards EnrichItem +
UpdateIntProperty unconditional-assign against a future != 0 regression.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-17 19:02:03 +02:00
parent 73adc3768c
commit 702d6e1e90

View file

@ -171,4 +171,31 @@ public sealed class ItemRepositoryTests
var repo = new ItemRepository();
Assert.False(repo.UpdateIntProperty(0xDEADBEEFu, 18u, 1));
}
[Fact]
public void UpdateIntProperty_uiEffectsClearedToZero_clearsEffects()
{
// The core "item with mana vs out of mana" promise: a draining item whose
// UiEffects clears to 0 must return to its base (un-tinted) icon. Guards
// against a future `if (value != 0)` regression on the unconditional assign.
var repo = new ItemRepository();
repo.AddOrUpdate(new ItemInstance { ObjectId = 0x500000ACu, Effects = 0x1u });
repo.UpdateIntProperty(0x500000ACu, ItemRepository.UiEffectsPropertyId, value: 0x1);
Assert.Equal(0x1u, repo.GetItem(0x500000ACu)!.Effects);
repo.UpdateIntProperty(0x500000ACu, ItemRepository.UiEffectsPropertyId, value: 0);
Assert.Equal(0u, repo.GetItem(0x500000ACu)!.Effects);
}
[Fact]
public void EnrichItem_effectsZero_clearsPriorEffects()
{
// A re-spawn (CreateObject) of a now-inert item carries effects=0; it must
// clear a previously-set effect (unconditional assign, not gated on != 0).
var repo = new ItemRepository();
repo.AddOrUpdate(new ItemInstance { ObjectId = 0x500000ADu, Effects = 0x1u });
bool ok = repo.EnrichItem(0x500000ADu, iconId: 0x06001234u, name: "Wand",
type: ItemType.Caster, effects: 0u);
Assert.True(ok);
Assert.Equal(0u, repo.GetItem(0x500000ADu)!.Effects);
}
}