Tests: equipment EditMode coverage (DR-027)
ItemDatabaseBlobTests (inline-mod round-trip on the 2nd item — the nested-BlobArray regression guard); EquipSystemTests (equip sets ability+mod+moves item; unequip reverses + restores DefaultAbility; equip-over swaps; full-bag swap rejected with no loss; non-equippable/absent/unresolvable no-op; strip leaves foreign SourceIds untouched). 236/236 EditMode pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
using NUnit.Framework;
|
||||
using ProjectM.Simulation;
|
||||
using Unity.Collections;
|
||||
using Unity.Entities;
|
||||
|
||||
namespace ProjectM.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// Regression guard for the Phase 1 inline-mod design: <see cref="ItemDatabaseBlob.TryGetItem"/> returns the
|
||||
/// def BY VALUE, so the inline <see cref="ItemModSpec"/> slots must survive that copy. (A nested BlobArray of
|
||||
/// mods would corrupt its relative-offset pointer on this copy and read empty — the blocker the inline layout
|
||||
/// avoids.) Looks up the SECOND item by id and reads a non-zero mod value: an index-1 lookup + a non-zero read
|
||||
/// is exactly what would expose an offset corruption that a length-only check on item 0 could miss.
|
||||
/// </summary>
|
||||
public class ItemDatabaseBlobTests
|
||||
{
|
||||
[Test]
|
||||
public void TryGetItem_RoundTrips_Inline_Mods_For_Second_Item()
|
||||
{
|
||||
var builder = new BlobBuilder(Allocator.Temp);
|
||||
ref var root = ref builder.ConstructRoot<ItemDatabaseBlob>();
|
||||
var arr = builder.Allocate(ref root.Items, 2);
|
||||
arr[0] = new ItemDefBlob { ItemId = 100, EquipSlot = EquipSlotId.Weapon };
|
||||
arr[1] = new ItemDefBlob
|
||||
{
|
||||
ItemId = 101,
|
||||
EquipSlot = EquipSlotId.Armor,
|
||||
Mod0 = new ItemModSpec { Target = (byte)StatTarget.MoveSpeed, Op = (byte)ModOp.PercentAdd, Value = 0.25f },
|
||||
Mod1 = new ItemModSpec { Target = (byte)StatTarget.Damage, Op = (byte)ModOp.Flat, Value = 7f },
|
||||
Mod2 = new ItemModSpec { Target = 255 },
|
||||
Mod3 = new ItemModSpec { Target = 255 },
|
||||
};
|
||||
var blob = builder.CreateBlobAssetReference<ItemDatabaseBlob>(Allocator.Persistent);
|
||||
builder.Dispose();
|
||||
|
||||
try
|
||||
{
|
||||
ref var db = ref blob.Value;
|
||||
Assert.IsTrue(db.TryGetItem(101, out var def), "Second item resolves by id.");
|
||||
Assert.AreEqual(EquipSlotId.Armor, def.EquipSlot);
|
||||
|
||||
var m0 = def.GetMod(0);
|
||||
Assert.AreEqual((byte)StatTarget.MoveSpeed, m0.Target, "Inline Mod0 target survives the by-value copy.");
|
||||
Assert.AreEqual(0.25f, m0.Value, 1e-4f, "Inline Mod0 value survives the by-value copy (would read 0 under a nested-blob corruption).");
|
||||
|
||||
var m1 = def.GetMod(1);
|
||||
Assert.AreEqual((byte)StatTarget.Damage, m1.Target);
|
||||
Assert.AreEqual(7f, m1.Value, 1e-4f);
|
||||
|
||||
Assert.AreEqual(255, def.GetMod(2).Target, "Unused inline slots stay 255.");
|
||||
}
|
||||
finally { blob.Dispose(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user