037ff66490
CoreSystemsTests (new): a breaching Husk drains + is consumed; idles at 0; regen fires once per interval in Calm only; no regen mid-Siege; caps at Max. CyclePhaseSystemTests: the soft-loss overrun edge ends the siege, drains the ledger, despawns husks, withholds the goal charge, and resolves once. StorageMathTests: DrainFraction floors per row, drops zeroed rows, clamps. SavePersistenceTests: CoreCurrent round-trips at v4; a pre-END-1 save with no CoreCurrent defaults to 0 (-> born full); the v3->v4 version pin updated. TuningConfig golden pin extended with the 3 Core defaults. See DR-034. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
187 lines
6.2 KiB
C#
187 lines
6.2 KiB
C#
using NUnit.Framework;
|
|
using ProjectM.Simulation;
|
|
using Unity.Entities;
|
|
|
|
namespace ProjectM.Tests
|
|
{
|
|
/// <summary>
|
|
/// Plain-Entities tests for <see cref="StorageMath"/> deposit/withdraw merge logic, using a temp World
|
|
/// and a real DynamicBuffer<StorageEntry> (no netcode world). Pins shared-storage semantics:
|
|
/// deposits merge by item id, withdraws clamp to available and drop empty rows.
|
|
/// </summary>
|
|
public class StorageMathTests
|
|
{
|
|
static (World world, Entity e) MakeWorld()
|
|
{
|
|
var world = new World("StorageMathTestWorld");
|
|
var e = world.EntityManager.CreateEntity(typeof(StorageEntry));
|
|
return (world, e);
|
|
}
|
|
|
|
[Test]
|
|
public void DrainFraction_Removes_Floored_Fraction_Of_Each_Row()
|
|
{
|
|
var (world, e) = MakeWorld();
|
|
try
|
|
{
|
|
var buf = world.EntityManager.GetBuffer<StorageEntry>(e);
|
|
StorageMath.Deposit(buf, 2, 100); // Ore
|
|
StorageMath.Deposit(buf, 4, 51); // Charge
|
|
StorageMath.DrainFraction(buf, 0.5f);
|
|
Assert.AreEqual(50, StorageMath.TotalOf(buf, 2), "100 -> floor(50) drained -> 50 left");
|
|
Assert.AreEqual(26, StorageMath.TotalOf(buf, 4), "51 -> floor(25) drained -> 26 left");
|
|
}
|
|
finally { world.Dispose(); }
|
|
}
|
|
|
|
[Test]
|
|
public void DrainFraction_Drops_Rows_That_Hit_Zero_And_Clamps_Above_One()
|
|
{
|
|
var (world, e) = MakeWorld();
|
|
try
|
|
{
|
|
var buf = world.EntityManager.GetBuffer<StorageEntry>(e);
|
|
StorageMath.Deposit(buf, 2, 4);
|
|
StorageMath.DrainFraction(buf, 1.5f); // clamps to 1.0 -> removes all -> row dropped
|
|
Assert.AreEqual(0, buf.Length, "a fully-drained row is removed");
|
|
}
|
|
finally { world.Dispose(); }
|
|
}
|
|
|
|
[Test]
|
|
public void DrainFraction_Zero_Is_NoOp()
|
|
{
|
|
var (world, e) = MakeWorld();
|
|
try
|
|
{
|
|
var buf = world.EntityManager.GetBuffer<StorageEntry>(e);
|
|
StorageMath.Deposit(buf, 2, 10);
|
|
StorageMath.DrainFraction(buf, 0f);
|
|
Assert.AreEqual(10, StorageMath.TotalOf(buf, 2), "0 fraction drains nothing");
|
|
}
|
|
finally { world.Dispose(); }
|
|
}
|
|
|
|
|
|
[Test]
|
|
public void Deposit_New_Item_Appends_Row()
|
|
{
|
|
var (world, e) = MakeWorld();
|
|
try
|
|
{
|
|
var buf = world.EntityManager.GetBuffer<StorageEntry>(e);
|
|
StorageMath.Deposit(buf, 1, 5);
|
|
Assert.AreEqual(1, buf.Length);
|
|
Assert.AreEqual((ushort)1, buf[0].ItemId);
|
|
Assert.AreEqual(5, buf[0].Count);
|
|
}
|
|
finally { world.Dispose(); }
|
|
}
|
|
|
|
[Test]
|
|
public void Deposit_Same_Item_Merges()
|
|
{
|
|
var (world, e) = MakeWorld();
|
|
try
|
|
{
|
|
var buf = world.EntityManager.GetBuffer<StorageEntry>(e);
|
|
StorageMath.Deposit(buf, 1, 5);
|
|
StorageMath.Deposit(buf, 1, 3);
|
|
Assert.AreEqual(1, buf.Length);
|
|
Assert.AreEqual(8, buf[0].Count);
|
|
}
|
|
finally { world.Dispose(); }
|
|
}
|
|
|
|
[Test]
|
|
public void Deposit_Different_Items_Separate_Rows()
|
|
{
|
|
var (world, e) = MakeWorld();
|
|
try
|
|
{
|
|
var buf = world.EntityManager.GetBuffer<StorageEntry>(e);
|
|
StorageMath.Deposit(buf, 1, 5);
|
|
StorageMath.Deposit(buf, 2, 7);
|
|
Assert.AreEqual(2, buf.Length);
|
|
}
|
|
finally { world.Dispose(); }
|
|
}
|
|
|
|
[Test]
|
|
public void Withdraw_Partial_Decrements()
|
|
{
|
|
var (world, e) = MakeWorld();
|
|
try
|
|
{
|
|
var buf = world.EntityManager.GetBuffer<StorageEntry>(e);
|
|
StorageMath.Deposit(buf, 1, 5);
|
|
int taken = StorageMath.Withdraw(buf, 1, 2);
|
|
Assert.AreEqual(2, taken);
|
|
Assert.AreEqual(1, buf.Length);
|
|
Assert.AreEqual(3, buf[0].Count);
|
|
}
|
|
finally { world.Dispose(); }
|
|
}
|
|
|
|
[Test]
|
|
public void Withdraw_To_Zero_Drops_Row()
|
|
{
|
|
var (world, e) = MakeWorld();
|
|
try
|
|
{
|
|
var buf = world.EntityManager.GetBuffer<StorageEntry>(e);
|
|
StorageMath.Deposit(buf, 1, 5);
|
|
int taken = StorageMath.Withdraw(buf, 1, 5);
|
|
Assert.AreEqual(5, taken);
|
|
Assert.AreEqual(0, buf.Length);
|
|
}
|
|
finally { world.Dispose(); }
|
|
}
|
|
|
|
[Test]
|
|
public void Withdraw_More_Than_Available_Clamps()
|
|
{
|
|
var (world, e) = MakeWorld();
|
|
try
|
|
{
|
|
var buf = world.EntityManager.GetBuffer<StorageEntry>(e);
|
|
StorageMath.Deposit(buf, 1, 3);
|
|
int taken = StorageMath.Withdraw(buf, 1, 10);
|
|
Assert.AreEqual(3, taken);
|
|
Assert.AreEqual(0, buf.Length);
|
|
}
|
|
finally { world.Dispose(); }
|
|
}
|
|
|
|
[Test]
|
|
public void Withdraw_Missing_Item_Is_NoOp()
|
|
{
|
|
var (world, e) = MakeWorld();
|
|
try
|
|
{
|
|
var buf = world.EntityManager.GetBuffer<StorageEntry>(e);
|
|
StorageMath.Deposit(buf, 1, 3);
|
|
int taken = StorageMath.Withdraw(buf, 99, 1);
|
|
Assert.AreEqual(0, taken);
|
|
Assert.AreEqual(1, buf.Length);
|
|
}
|
|
finally { world.Dispose(); }
|
|
}
|
|
|
|
[Test]
|
|
public void Deposit_Ignores_NonPositive_And_ZeroItem()
|
|
{
|
|
var (world, e) = MakeWorld();
|
|
try
|
|
{
|
|
var buf = world.EntityManager.GetBuffer<StorageEntry>(e);
|
|
StorageMath.Deposit(buf, 1, 0);
|
|
StorageMath.Deposit(buf, 1, -5);
|
|
StorageMath.Deposit(buf, 0, 5);
|
|
Assert.AreEqual(0, buf.Length);
|
|
}
|
|
finally { world.Dispose(); }
|
|
}
|
|
}
|
|
}
|