using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using MrGameEng.Graphics; using Xunit; namespace MrGameEng.Tilemaps.Tests; public class TileGridTests { [Fact] public void NewGrid_IsEmpty() { var grid = new TileGrid(4, 3); Assert.Equal(4, grid.Width); Assert.Equal(3, grid.Height); for (var y = 0; y < 3; y++) { for (var x = 0; x < 4; x++) { Assert.Equal(0, grid[x, y]); } } } [Fact] public void SetGet_RoundtripsPerCell() { var grid = new TileGrid(3, 3); grid[2, 1] = 7; Assert.Equal(7, grid[2, 1]); Assert.Equal(0, grid[1, 2]); } [Fact] public void Fill_SetsEveryCell() { var grid = new TileGrid(5, 5); grid.Fill(3); Assert.Equal(3, grid[0, 0]); Assert.Equal(3, grid[4, 4]); } [Theory] [InlineData(-1, 0)] [InlineData(0, -1)] [InlineData(3, 0)] [InlineData(0, 2)] public void OutOfBounds_Throws(int x, int y) { var grid = new TileGrid(3, 2); Assert.False(grid.Contains(x, y)); Assert.Throws(() => grid[x, y]); Assert.Throws(() => grid[x, y] = 1); } [Theory] [InlineData(0, 0)] [InlineData(-1, 1)] public void InvalidSize_Throws(int width, int height) { Assert.Throws(() => new TileGrid(width, height)); } } public class TileSetTests { // Texture2D == null допустим в headless-тестах (см. Texture2DRegion). private static Texture2DRegion Region(int size = 16) => new(null!, new Rectangle(0, 0, size, size)); [Fact] public void Add_ReturnsSequentialIds_StartingAtOne() { var tiles = new TileSet(); var first = tiles.Add(Region()); var second = tiles.Add(Region(), Color.Red); Assert.Equal(1, first); Assert.Equal(2, second); Assert.Equal(3, tiles.Count); Assert.Equal(Color.White, tiles[first].Color); Assert.Equal(Color.Red, tiles[second].Color); } [Fact] public void EmptyTileZero_HasNoRegion() { var tiles = new TileSet(); Assert.Null(tiles[0].Region); } } public class TilemapMathTests { [Fact] public void CameraInsideMap_ReturnsClampedRange() { var cull = new RectF(35f, 18f, 40f, 30f); // правый край 75, нижний 48 var visible = TilemapMath.VisibleCells(in cull, Vector2.Zero, 16f, 10, 10, out var x0, out var y0, out var x1, out var y1); Assert.True(visible); Assert.Equal((2, 1, 4, 3), (x0, y0, x1, y1)); } [Fact] public void MapOffsetByOrigin_ShiftsRange() { var cull = new RectF(0f, 0f, 64f, 64f); var visible = TilemapMath.VisibleCells(in cull, new Vector2(-32f, -32f), 16f, 100, 100, out var x0, out var y0, out var x1, out var y1); Assert.True(visible); Assert.Equal((2, 2, 6, 6), (x0, y0, x1, y1)); } [Fact] public void CameraLargerThanMap_ClampsToWholeGrid() { var cull = new RectF(-1000f, -1000f, 5000f, 5000f); var visible = TilemapMath.VisibleCells(in cull, Vector2.Zero, 16f, 8, 6, out var x0, out var y0, out var x1, out var y1); Assert.True(visible); Assert.Equal((0, 0, 7, 5), (x0, y0, x1, y1)); } [Theory] [InlineData(200f, 0f)] // справа от карты [InlineData(-200f, 0f)] // слева [InlineData(0f, 200f)] // ниже public void CameraOutsideMap_ReturnsFalse(float offsetX, float offsetY) { var cull = new RectF(offsetX, offsetY, 100f, 100f); var visible = TilemapMath.VisibleCells(in cull, new Vector2(-150f, -150f), 16f, 8, 8, out _, out _, out _, out _); Assert.False(visible); } }