using FluentAssertions; using Sand.ChunkPrototype; namespace Sand.ChunkPrototype.Tests; public sealed class PrototypeChunkResidencyWorldTests { [Fact] public void MoveOccupiedAcrossChunkBoundaryUpdatesCountsAndDirtyChunks() { var world = new PrototypeChunkResidencyWorld(new ChunkResidencyConfig(4, 4, Capacity: 16)); world.SetOccupied(3, 1); world.ClearDirtyChunks(); var moved = world.MoveOccupied(3, 1, 4, 1); moved.Should().BeTrue(); world.IsOccupied(3, 1).Should().BeFalse(); world.IsOccupied(4, 1).Should().BeTrue(); world.GetChunkOccupancyCount(0, 0).Should().Be(0); world.GetChunkOccupancyCount(1, 0).Should().Be(1); world.DirtyChunks.Should().BeEquivalentTo([(0, 0), (1, 0)]); } [Fact] public void UnloadEmptyChunksRemovesChunksAfterClearingOccupancy() { var world = new PrototypeChunkResidencyWorld(new ChunkResidencyConfig(4, 4, Capacity: 16)); world.SetOccupied(1, 1); world.SetOccupied(9, 1); world.ClearOccupied(1, 1); var unloaded = world.UnloadEmptyChunks(); unloaded.Should().Be(1); world.IsChunkLoaded(0, 0).Should().BeFalse(); world.IsChunkLoaded(2, 0).Should().BeTrue(); world.ActiveChunkCount.Should().Be(1); } [Fact] public void UnloadInactiveChunksKeepsActiveNeighborsWithinMargin() { var world = new PrototypeChunkResidencyWorld(new ChunkResidencyConfig(4, 4, Capacity: 32)); world.SetOccupied(4, 4); world.SetOccupied(20, 20); world.ClearOccupied(20, 20); world.SetOccupied(8, 4); var unloaded = world.UnloadInactiveChunks(marginChunks: 1); unloaded.Should().BeGreaterThanOrEqualTo(1); world.IsChunkLoaded(1, 1).Should().BeTrue(); world.IsChunkLoaded(2, 1).Should().BeTrue(); world.IsChunkLoaded(5, 5).Should().BeFalse(); } [Fact] public void ClearDirtyChunksResetsDirtyChunkTracking() { var world = new PrototypeChunkResidencyWorld(); world.SetOccupied(2, 2); world.SetOccupied(40, 2); world.DirtyChunkCount.Should().Be(2); world.ClearDirtyChunks(); world.DirtyChunkCount.Should().Be(0); world.DirtyChunks.Should().BeEmpty(); } }