Files
Project-M/Assets/_Project/Tests/EditMode/DebugCommandReceiveSystemTests.cs
T
2026-06-04 13:45:46 -07:00

133 lines
5.9 KiB
C#

using NUnit.Framework;
using ProjectM.Server;
using ProjectM.Simulation;
using Unity.Core;
using Unity.Entities;
using Unity.Mathematics;
using Unity.NetCode;
using Unity.Transforms;
namespace ProjectM.Tests
{
/// <summary>
/// Plain-Entities EditMode tests for the editor-only <see cref="DebugCommandReceiveSystem"/> — the
/// server-side dev-tools RPC dispatcher. A bare world is seeded with the relevant singletons + a
/// DebugCommandRequest (+ ReceiveRpcCommandRequest) entity. These pin that grant-resource deposits to the
/// ledger, spawn-wave arms the pending siege, end-siege forces the wave to Lull + clears pending, and a
/// sender-targeted teleport resolves the player from the source connection and flips its region.
/// </summary>
public class DebugCommandReceiveSystemTests
{
static (World world, SimulationSystemGroup group) MakeWorld(string name)
{
var world = new World(name);
var group = world.GetOrCreateSystemManaged<SimulationSystemGroup>();
group.AddSystemToUpdateList(world.GetOrCreateSystem<DebugCommandReceiveSystem>());
group.SortSystems();
world.SetTime(new TimeData(elapsedTime: 0f, deltaTime: 1f / 60f));
return (world, group);
}
static Entity MakeRequest(EntityManager em, byte op, int argA, int argB, Entity sourceConnection)
{
var e = em.CreateEntity(typeof(DebugCommandRequest), typeof(ReceiveRpcCommandRequest));
em.SetComponentData(e, new DebugCommandRequest { Op = op, ArgA = argA, ArgB = argB });
em.SetComponentData(e, new ReceiveRpcCommandRequest { SourceConnection = sourceConnection });
return e;
}
[Test]
public void GrantResource_Deposits_To_Ledger()
{
var (world, group) = MakeWorld("DebugGrantResource");
using (world)
{
var em = world.EntityManager;
var ledger = em.CreateEntity(typeof(ResourceLedger), typeof(StorageEntry));
MakeRequest(em, DebugOp.GrantResource, ResourceId.Aether, 50, Entity.Null);
group.Update();
var buf = em.GetBuffer<StorageEntry>(ledger);
int aether = 0;
for (int i = 0; i < buf.Length; i++)
if (buf[i].ItemId == ResourceId.Aether) aether = buf[i].Count;
Assert.AreEqual(50, aether, "GrantResource deposits the amount into the shared ledger.");
}
}
[Test]
public void SpawnWave_Arms_PendingSiege()
{
var (world, group) = MakeWorld("DebugSpawnWave");
using (world)
{
var em = world.EntityManager;
var dir = em.CreateEntity(typeof(CycleState), typeof(ThreatState));
em.SetComponentData(dir, new CycleState { Phase = CyclePhase.Calm });
MakeRequest(em, DebugOp.SpawnWave, 8, 0, Entity.Null);
group.Update();
Assert.AreEqual(8, em.GetComponentData<ThreatState>(dir).PendingSiegeSize,
"SpawnWave arms a pending siege of the requested size.");
}
}
[Test]
public void EndSiege_Forces_WaveState_Lull_And_Clears_Pending()
{
var (world, group) = MakeWorld("DebugEndSiege");
using (world)
{
var em = world.EntityManager;
var dir = em.CreateEntity(typeof(CycleState), typeof(ThreatState));
em.SetComponentData(dir, new CycleState { Phase = CyclePhase.Siege });
em.SetComponentData(dir, new ThreatState { PendingSiegeSize = 5, SiegeStartTick = 100 });
var wave = em.CreateEntity(typeof(WaveState));
em.SetComponentData(wave, new WaveState { Phase = WavePhase.Spawning, RemainingToSpawn = 3 });
for (int i = 0; i < 2; i++)
em.CreateEntity(typeof(EnemyTag));
MakeRequest(em, DebugOp.EndSiege, 0, 0, Entity.Null);
group.Update();
var w = em.GetComponentData<WaveState>(wave);
Assert.AreEqual(WavePhase.Lull, w.Phase, "EndSiege drives the wave to Lull.");
Assert.AreEqual(0, w.RemainingToSpawn, "EndSiege stops further spawning.");
Assert.AreEqual(0, em.GetComponentData<ThreatState>(dir).PendingSiegeSize, "EndSiege clears any pending siege.");
using var husks = em.CreateEntityQuery(typeof(EnemyTag));
Assert.AreEqual(0, husks.CalculateEntityCount(), "EndSiege culls the remaining Husks.");
}
}
[Test]
public void Teleport_Resolves_Sender_Only()
{
var (world, group) = MakeWorld("DebugTeleport");
using (world)
{
var em = world.EntityManager;
var connection = em.CreateEntity(typeof(NetworkId));
em.SetComponentData(connection, new NetworkId { Value = 1 });
var player = em.CreateEntity(typeof(PlayerTag), typeof(GhostOwner), typeof(RegionTag), typeof(LocalTransform));
em.SetComponentData(player, new GhostOwner { NetworkId = 1 });
em.SetComponentData(player, new RegionTag { Region = RegionId.Base });
em.SetComponentData(player, LocalTransform.FromPosition(new float3(0, 1, 0)));
MakeRequest(em, DebugOp.Teleport, RegionId.Expedition, 0, connection);
group.Update();
Assert.AreEqual(RegionId.Expedition, em.GetComponentData<RegionTag>(player).Region,
"Teleport flips the SENDER's region.");
Assert.Greater(em.GetComponentData<LocalTransform>(player).Position.x, 500f,
"Teleport moves the sender to the expedition region (far +X).");
}
}
}
}