ModernUO/Projects/UOContent.Tests/Tests/PropertyList/BaseArmorPropertiesTests.cs
Kamron Batman f7c44f7c10
refactor(opl): Consolidate AOS attribute OPL emission into per-family GetProperties (#2501)
## Summary

Consolidates the duplicated inline AOS attribute → `ObjectPropertyList` emission that each item base copy-pastes into per-family `GetProperties(IPropertyList)` methods, mirroring the existing `AosSkillBonuses.GetProperties` precedent.

### Per-family `GetProperties(IPropertyList)`
- **`AosAttributes`** — the 24 common attributes in canonical cliloc-ascending order, with optional `damageBonus` / `hitChanceBonus` / `luckBonus` params so item-computed bonuses (e.g. `GetDamageBonus()`) stay out of the family type.
- **`AosWeaponAttributes`** — `UseBestSkill`, the `Hit*` block (1060416–1060430), `MageWeapon` (`30 - prop`), `SelfRepair`.
- **`AosArmorAttributes`** — `MageArmor`, `SelfRepair` (the always-direct members; `LowerStatReq`/`DurabilityBonus` stay inline since they're item-computed in armor but container-direct in clothing).

### Rewired all 6 `AosAttributes`-emitting item bases
`BaseJewel`, `BaseArmor`, `BaseClothing`, `BaseWeapon`, `BaseTalisman`, `Spellbook` now call the family methods instead of inlining the chain. Net: large dedup in `BaseWeapon`/`BaseArmor`/`BaseClothing`/`BaseTalisman`/`Spellbook`.

## Behavior change: tooltip line **order** (set preserved)

This is **not** a pure no-op refactor, and that's unavoidable. Today the families are emitted **interleaved in cliloc order**, and the relative order differs per item class — e.g. `BonusDex` (1060409) is emitted early in `BaseArmor` but **after** the `Hit*` block in `BaseWeapon`. No single emission order reproduces every class byte-for-byte, so consolidating into contiguous per-family blocks necessarily **de-interleaves**: lines regroup **specific → general** (family-specific, then common `AosAttributes`).

- The **set** of emitted `(cliloc, argument)` lines per item is preserved **exactly** — nothing dropped, added, or value-changed.
- Only the **order** of lines within a tooltip changes for `BaseArmor` / `BaseWeapon` / `BaseClothing`. `BaseJewel` / `BaseTalisman` / `Spellbook` were already canonical, so those are byte-identical.

## Tests
- **Golden set-invariance tests** per item base (`BaseArmor/Clothing/Jewel/Weapon/Talisman/Spellbook PropertiesTests`) — each was written to pass against current `main` **before** the rewire (locking the emitted-line set), then confirmed still passing after, proving no line is lost/added/changed.
- Family-level unit tests for each `GetProperties` (canonical order, computed-bonus folding, the `AosArmorAttributes` exclusions).
- `dotnet build` clean; full `UOContent.Tests` green. (Pre-existing `AccountPacket`/`GumpPacket`/`MobilePacket`/`ClientEnumerator` golden-test failures reproduce on unmodified `main` and are unrelated to this change.)
2026-07-02 19:40:54 -07:00

40 lines
1.3 KiB
C#

using Server.Items;
using Xunit;
namespace UOContent.Tests;
[Collection("Sequential UOContent Tests")]
public class BaseArmorPropertiesTests
{
[Fact]
public void Armor_AttributeLineSet_Preserved()
{
var armor = new PlateChest();
try
{
armor.Attributes.DefendChance = 5;
armor.Attributes.BonusDex = 8;
armor.Attributes.Luck = 40;
armor.Attributes.SpellChanneling = 1;
armor.Attributes.IncreasedKarmaLoss = 2;
armor.ArmorAttributes.MageArmor = 1;
armor.ArmorAttributes.SelfRepair = 3;
armor.ArmorAttributes.LowerStatReq = 50;
var map = ItemOplTestHelper.DecodeAttributeLines(armor);
Assert.Equal("5", map[1060408]); // DefendChance
Assert.Equal("8", map[1060409]); // BonusDex
Assert.Equal("40", map[1060436]); // Luck (GetLuckBonus()==0 unequipped)
Assert.Equal("", map[1060482]); // SpellChanneling
Assert.Equal("2", map[1075210]); // IncreasedKarmaLoss
Assert.Equal("", map[1060437]); // MageArmor
Assert.Equal("3", map[1060450]); // SelfRepair
Assert.Equal("50", map[1060435]); // LowerStatReq (inline via GetLowerStatReq)
}
finally
{
armor.Delete();
}
}
}