using NUnit.Framework; using ProjectM.Simulation; using Unity.Entities; using UnityEngine; namespace ProjectM.Tests { /// /// Pure tests for the save FOUNDATION: the JSON schema round-trips (JsonUtility), version handling is safe, /// and the born-correct ledger apply () the server spawn system uses to /// overwrite a director's StorageEntry buffer from a staged PendingSave. /// public class SavePersistenceTests { [Test] public void SaveData_Json_RoundTrip_PreservesFields() { var data = new SaveData { GoalCharge = 42, GoalTarget = 10, Ledger = new[] { new LedgerRow { ItemId = 1, Count = 5 }, new LedgerRow { ItemId = 2, Count = 9 }, }, SavedAtMs = 1234567890123L, }; var json = JsonUtility.ToJson(data); var back = JsonUtility.FromJson(json); Assert.AreEqual(SaveData.CurrentVersion, back.Version); Assert.AreEqual(42, back.GoalCharge); Assert.AreEqual(10, back.GoalTarget); Assert.AreEqual(2, back.Ledger.Length); Assert.AreEqual(1, back.Ledger[0].ItemId); Assert.AreEqual(5, back.Ledger[0].Count); Assert.AreEqual(2, back.Ledger[1].ItemId); Assert.AreEqual(9, back.Ledger[1].Count); Assert.AreEqual(1234567890123L, back.SavedAtMs); } [Test] public void SaveData_EmptyJson_DoesNotThrow_And_EmptyLedgerRoundTrips() { Assert.DoesNotThrow(() => JsonUtility.FromJson("{}")); var empty = new SaveData { GoalCharge = 0, GoalTarget = 10 }; var back = JsonUtility.FromJson(JsonUtility.ToJson(empty)); Assert.IsNotNull(back.Ledger); Assert.AreEqual(0, back.Ledger.Length); } [Test] public void SaveData_OldVersion_IsDetectable() { // A stale-version blob round-trips with its Version intact, so SaveService.Load rejects it (-> New Game). var old = new SaveData { Version = 0, GoalCharge = 7 }; var back = JsonUtility.FromJson(JsonUtility.ToJson(old)); Assert.AreEqual(0, back.Version); Assert.AreNotEqual(SaveData.CurrentVersion, back.Version); } [Test] public void WriteLedger_Overwrites_Destination_From_Staged_Rows() { using var world = new World("SaveApplyTest"); var em = world.EntityManager; var e = em.CreateEntity(); em.AddBuffer(e); em.AddBuffer(e); var src = em.GetBuffer(e); src.Add(new PendingSaveLedgerRow { ItemId = 3, Count = 7 }); src.Add(new PendingSaveLedgerRow { ItemId = 5, Count = 12 }); var dest = em.GetBuffer(e); dest.Add(new StorageEntry { ItemId = 99, Count = 1 }); // pre-existing junk that must be cleared SaveApply.WriteLedger(em.GetBuffer(e), em.GetBuffer(e)); var result = em.GetBuffer(e); Assert.AreEqual(2, result.Length); Assert.AreEqual(3, result[0].ItemId); Assert.AreEqual(7, result[0].Count); Assert.AreEqual(5, result[1].ItemId); Assert.AreEqual(12, result[1].Count); } [Test] public void WriteLedger_EmptySource_ClearsDestination() { using var world = new World("SaveApplyEmptyTest"); var em = world.EntityManager; var e = em.CreateEntity(); em.AddBuffer(e); em.AddBuffer(e); var dest = em.GetBuffer(e); dest.Add(new StorageEntry { ItemId = 1, Count = 1 }); SaveApply.WriteLedger(em.GetBuffer(e), em.GetBuffer(e)); Assert.AreEqual(0, em.GetBuffer(e).Length); } } }