Files
Project-M/Assets/_Project/Tests/EditMode/StatMathTests.cs
T
2026-05-31 21:35:12 -07:00

90 lines
3.3 KiB
C#

using NUnit.Framework;
using ProjectM.Simulation;
using Unity.Collections;
namespace ProjectM.Tests
{
/// <summary>
/// Pure-function tests for <see cref="StatMath.Apply"/> (no ECS world), mirroring AutoTargetTests.
/// Pins the ARPG fold order: effective = (base + sum flat) * (1 + sum percentAdd) * product(1 + percentMult).
/// </summary>
public class StatMathTests
{
static StatModifier Mod(StatTarget target, ModOp op, float value) =>
new StatModifier { Target = (byte)target, Op = (byte)op, Value = value };
static float Apply(float baseValue, StatTarget target, params StatModifier[] mods)
{
using var arr = new NativeArray<StatModifier>(mods, Allocator.Temp);
return StatMath.Apply(baseValue, target, arr);
}
[Test]
public void Empty_Returns_Base()
{
using var arr = new NativeArray<StatModifier>(0, Allocator.Temp);
Assert.AreEqual(10f, StatMath.Apply(10f, StatTarget.Damage, arr), 1e-4f);
}
[Test]
public void Flat_Adds()
{
Assert.AreEqual(15f, Apply(10f, StatTarget.Damage, Mod(StatTarget.Damage, ModOp.Flat, 5f)), 1e-4f);
}
[Test]
public void Flats_Sum()
{
Assert.AreEqual(18f, Apply(10f, StatTarget.Damage,
Mod(StatTarget.Damage, ModOp.Flat, 5f),
Mod(StatTarget.Damage, ModOp.Flat, 3f)), 1e-4f);
}
[Test]
public void PercentAdd_Pools()
{
// base 10 * (1 + 0.2 + 0.3) = 15
Assert.AreEqual(15f, Apply(10f, StatTarget.Damage,
Mod(StatTarget.Damage, ModOp.PercentAdd, 0.2f),
Mod(StatTarget.Damage, ModOp.PercentAdd, 0.3f)), 1e-4f);
}
[Test]
public void PercentMult_Multiplies_Separately()
{
// base 10 * (1+0.5) * (1+0.2) = 18 (note: distinct from a pooled +0.7 = 17)
Assert.AreEqual(18f, Apply(10f, StatTarget.Damage,
Mod(StatTarget.Damage, ModOp.PercentMult, 0.5f),
Mod(StatTarget.Damage, ModOp.PercentMult, 0.2f)), 1e-4f);
}
[Test]
public void Combined_Applies_In_Standard_Order()
{
// (10 + 5) * (1 + 0.2) * (1 + 0.5) = 27
Assert.AreEqual(27f, Apply(10f, StatTarget.Damage,
Mod(StatTarget.Damage, ModOp.Flat, 5f),
Mod(StatTarget.Damage, ModOp.PercentAdd, 0.2f),
Mod(StatTarget.Damage, ModOp.PercentMult, 0.5f)), 1e-4f);
}
[Test]
public void Other_Targets_Are_Ignored()
{
// A MoveSpeed modifier must not affect a Damage query.
Assert.AreEqual(10f, Apply(10f, StatTarget.Damage,
Mod(StatTarget.MoveSpeed, ModOp.Flat, 100f),
Mod(StatTarget.MoveSpeed, ModOp.PercentAdd, 5f)), 1e-4f);
}
[Test]
public void Mixed_Targets_Fold_Independently()
{
var dmg = Mod(StatTarget.Damage, ModOp.Flat, 5f);
var spd = Mod(StatTarget.MoveSpeed, ModOp.PercentAdd, 0.5f);
Assert.AreEqual(15f, Apply(10f, StatTarget.Damage, dmg, spd), 1e-4f);
Assert.AreEqual(9f, Apply(6f, StatTarget.MoveSpeed, dmg, spd), 1e-4f);
}
}
}