Chessistics/chessistics-tests/Simulation/QuickSaveTests.cs

182 lines
5.6 KiB
C#
Raw Normal View History

using Chessistics.Engine.Commands;
using Chessistics.Engine.Events;
using Chessistics.Engine.Model;
using Chessistics.Tests.Helpers;
using Xunit;
namespace Chessistics.Tests.Simulation;
public class QuickSaveTests
{
private SimHelper CreateSim()
{
var level = new BoardBuilder(4, 4)
.WithProduction(0, 0, "Scierie", CargoType.Wood, amount: 1)
.WithDemand(3, 0, "Depot", CargoType.Wood, 3, 30)
.WithStock(PieceKind.Rook, 3)
.Build();
return SimHelper.FromLevel(level);
}
[Fact]
public void QuickSave_ReturnsSavedEvent()
{
var sim = CreateSim();
var events = sim.Sim.QuickSave();
Assert.Single(events);
Assert.IsType<StateSavedEvent>(events[0]);
}
[Fact]
public void QuickLoad_WithoutSave_ReturnsEmpty()
{
var sim = CreateSim();
var events = sim.Sim.QuickLoad();
Assert.Empty(events);
}
[Fact]
public void QuickLoad_AfterSave_EmitsRestoredEvent()
{
var sim = CreateSim();
sim.Sim.QuickSave();
var events = sim.Sim.QuickLoad();
Assert.Single(events);
var restored = Assert.IsType<StateRestoredEvent>(events[0]);
Assert.NotNull(restored.Snapshot);
}
[Fact]
public void Save_MutateState_Load_RestoresPreviousState()
{
var sim = CreateSim();
// Place a piece, then save
sim.Place(PieceKind.Rook, (0, 0), (1, 0));
sim.Sim.QuickSave();
var beforeSnap = sim.Snapshot;
Assert.Single(beforeSnap.Pieces);
Assert.Equal(3 - 1, beforeSnap.RemainingStock[PieceKind.Rook]);
// Mutate: place another piece, step simulation
sim.Place(PieceKind.Rook, (0, 1), (1, 1));
sim.Step();
sim.Step();
var dirtySnap = sim.Snapshot;
Assert.Equal(2, dirtySnap.Pieces.Count);
Assert.Equal(2, dirtySnap.TurnNumber);
// Load: should match beforeSnap
sim.Sim.QuickLoad();
var afterSnap = sim.Snapshot;
Assert.Single(afterSnap.Pieces);
Assert.Equal(0, afterSnap.TurnNumber);
Assert.Equal(3 - 1, afterSnap.RemainingStock[PieceKind.Rook]);
Assert.Equal(beforeSnap.Pieces[0].Id, afterSnap.Pieces[0].Id);
Assert.Equal(beforeSnap.Pieces[0].StartCell, afterSnap.Pieces[0].StartCell);
}
[Fact]
public void Load_IsIndependent_FromFurtherChanges()
{
// Saving should not alias; mutating state after save must not affect the save.
var sim = CreateSim();
sim.Place(PieceKind.Rook, (0, 0), (1, 0));
sim.Sim.QuickSave();
// Mutate after save
sim.Place(PieceKind.Rook, (0, 1), (1, 1));
sim.Step();
// Load should restore to 1 piece, turn 0
sim.Sim.QuickLoad();
var snap = sim.Snapshot;
Assert.Single(snap.Pieces);
Assert.Equal(0, snap.TurnNumber);
// Mutate again, load again — save still usable
sim.Place(PieceKind.Rook, (0, 2), (1, 2));
sim.Sim.QuickLoad();
snap = sim.Snapshot;
Assert.Single(snap.Pieces);
}
[Fact]
public void QuickSave_PreservesCampaignProgression()
{
var campaign = CampaignBuilder();
var sim = SimHelper.FromCampaign(campaign);
sim.Sim.ProcessCommand(new LoadCampaignCommand());
sim.Place(PieceKind.Pawn, (0, 0), (1, 0));
sim.Sim.QuickSave();
var before = sim.Snapshot;
Assert.Equal(0, before.Campaign!.CurrentMissionIndex);
// Mutate
sim.Step();
sim.Step();
sim.Sim.QuickLoad();
var after = sim.Snapshot;
Assert.Equal(before.Campaign!.CurrentMissionIndex, after.Campaign!.CurrentMissionIndex);
Assert.Equal(before.Pieces.Count, after.Pieces.Count);
Assert.Equal(0, after.TurnNumber);
}
[Fact]
public void MultipleSlots_AreIndependent()
{
var sim = CreateSim();
sim.Place(PieceKind.Rook, (0, 0), (1, 0));
sim.Sim.QuickSave(slot: 1);
sim.Place(PieceKind.Rook, (0, 1), (1, 1));
sim.Sim.QuickSave(slot: 2);
// Slot 1 should have 1 piece; slot 2 should have 2
sim.Sim.QuickLoad(slot: 1);
Assert.Single(sim.Snapshot.Pieces);
sim.Sim.QuickLoad(slot: 2);
Assert.Equal(2, sim.Snapshot.Pieces.Count);
}
private static CampaignDef CampaignBuilder()
{
return new CampaignDef
{
Name = "TestCampaign",
InitialWidth = 4,
InitialHeight = 4,
Missions = new List<MissionDef>
{
new()
{
Id = 1,
Name = "M1",
TerrainPatch = new TerrainPatch
{
NewWidth = 4,
NewHeight = 4,
Cells = new List<PatchCell>
{
new() { Col = 0, Row = 0, Type = CellType.Production,
Production = new ProductionDef(new Coords(0, 0), "S", CargoType.Wood, 1) },
new() { Col = 3, Row = 0, Type = CellType.Demand,
Demand = new DemandDef(new Coords(3, 0), "D", CargoType.Wood, 3) }
}
},
UnlockedPieces = new List<PieceKind> { PieceKind.Pawn },
UnlockedLevels = new List<PieceUpgrade> { new(PieceKind.Pawn, 1) },
Stock = new List<PieceStock> { new(PieceKind.Pawn, 4) }
}
}
};
}
}