Files
RobustToolbox/Robust.UnitTesting/Shared/Map/MapChunk_Tests.cs
T
AcruidandPieter-Jan Briers 1b3cc8aba6 Grid Bounds (#800)
* Added centered unit box static field to Box2.

* MapGrid is more testable.

* Added some unit tests for MapGrid.
Fixed bug in MapChunk.GridTileToLocal().
MapGrid.UpdateAABB() actually expands properly now.

* Moved IMapChunk to Robust.Shared.Map.
Moved Chunk class out of MapManager class.

* Added unit tests for MapChunk.

* Bounds reduce by 1, so almost working.

* Now bound shrinking works :D

* Moved MapGrid out of MapManager.
Moved IMapGrid into the Shared/Map folder.
Replaced all calls to IMapGrid.ParentMap.Index with IMapGrid.ParentMapId.

* Added more MapGrid unit tests.
Fixed a bug in TryGetTileRef.
2019-04-29 12:43:20 +02:00

456 lines
17 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Moq;
using NUnit.Framework;
using Robust.Shared.GameObjects.Components.Transform;
using Robust.Shared.Map;
using Robust.Shared.Timing;
namespace Robust.UnitTesting.Shared.Map
{
[TestFixture, Parallelizable, TestOf(typeof(MapChunk))]
class MapChunk_Tests
{
[Test]
public void GetChunkSize()
{
var chunk = MapChunkFactory(7, 9);
Assert.That(chunk.ChunkSize, Is.EqualTo((ushort)8));
}
[Test]
public void GetIndices()
{
var chunk = MapChunkFactory(7, 9);
Assert.That(chunk.X, Is.EqualTo(7));
Assert.That(chunk.Y, Is.EqualTo(9));
Assert.That(chunk.Indices, Is.EqualTo(new MapIndices(7,9)));
}
[Test]
public void ConstructorSetsLastTick()
{
var chunk = MapChunkFactory(7, 9);
Assert.That(chunk.LastModifiedTick, Is.EqualTo(new GameTick(11)));
}
[Test]
public void SetTileThrowsOutOfRange()
{
var chunk = MapChunkFactory(7, 9);
Assert.Throws<ArgumentOutOfRangeException>((() => chunk.SetTile(8,0, new Tile())));
Assert.Throws<ArgumentOutOfRangeException>((() => chunk.SetTile(0, 8, new Tile())));
}
[Test]
public void SetTileModifiesLastTick()
{
var curTick = new GameTick(11);
var mapGrid = new Mock<IMapGridInternal>();
mapGrid.SetupGet(f => f.CurTick).Returns((() => curTick));
mapGrid.SetupGet(f => f.ParentMapId).Returns(new MapId(11));
mapGrid.SetupGet(f => f.Index).Returns(new GridId(13));
var chunk = new MapChunk(mapGrid.Object, 7, 9, 8);
curTick = new GameTick(13);
chunk.SetTile(3, 5, new Tile(1, 3));
Assert.That(chunk.LastModifiedTick, Is.EqualTo(new GameTick(13)));
}
[Test]
public void SetTileDuplicateDoesNotModifyLastTick()
{
var curTick = new GameTick(11);
var mapGrid = new Mock<IMapGridInternal>();
mapGrid.SetupGet(f => f.CurTick).Returns((() => curTick));
mapGrid.SetupGet(f => f.ParentMapId).Returns(new MapId(11));
mapGrid.SetupGet(f => f.Index).Returns(new GridId(13));
var chunk = new MapChunk(mapGrid.Object, 7, 9, 8);
curTick = new GameTick(13);
chunk.SetTile(3, 5, new Tile(1, 3));
curTick = new GameTick(14);
chunk.SetTile(3, 5, new Tile(1, 3));
Assert.That(chunk.LastModifiedTick, Is.EqualTo(new GameTick(13)));
}
[Test]
public void GetTileRefByIndex()
{
var chunk = MapChunkFactory(7, 9);
chunk.SetTile(3, 5, new Tile(1, 3));
var result = chunk.GetTileRef(3, 5);
Assert.That(result.X, Is.EqualTo(8 * 7 + 3));
Assert.That(result.Y, Is.EqualTo(8 * 9 + 5));
Assert.That(result.Tile.TypeId, Is.EqualTo(1));
Assert.That(result.Tile.Data, Is.EqualTo((ushort) 3));
Assert.That(result.GridIndex, Is.EqualTo(new GridId(13)));
Assert.That(result.MapIndex, Is.EqualTo(new MapId(11)));
}
[Test]
public void GetTileRefByIndices()
{
var chunk = MapChunkFactory(7, 9);
chunk.SetTile(3, 5, new Tile(1, 3));
var result = chunk.GetTileRef(new MapIndices(3, 5));
Assert.That(result.X, Is.EqualTo(8 * 7 + 3));
Assert.That(result.Y, Is.EqualTo(8 * 9 + 5));
Assert.That(result.Tile.TypeId, Is.EqualTo(1));
Assert.That(result.Tile.Data, Is.EqualTo((ushort)3));
Assert.That(result.GridIndex, Is.EqualTo(new GridId(13)));
Assert.That(result.MapIndex, Is.EqualTo(new MapId(11)));
}
[Test]
public void GetTileRefThrowsOutOfRange()
{
var chunk = MapChunkFactory(7, 9);
Assert.Throws<ArgumentOutOfRangeException>((() => chunk.GetTileRef(8, 0)));
Assert.Throws<ArgumentOutOfRangeException>((() => chunk.GetTileRef(0, 8)));
Assert.Throws<ArgumentOutOfRangeException>((() => chunk.GetTileRef(new MapIndices(8,0))));
Assert.Throws<ArgumentOutOfRangeException>((() => chunk.GetTileRef(new MapIndices(0, 8))));
}
[Test]
public void GetTileByIndex()
{
var chunk = MapChunkFactory(7, 9);
chunk.SetTile(3, 5, new Tile(1, 3));
var result = chunk.GetTile(3, 5);
Assert.That(result.TypeId, Is.EqualTo(1));
Assert.That(result.Data, Is.EqualTo((ushort)3));
}
[Test]
public void GetTileByIndexThrowsOutOfRange()
{
var chunk = MapChunkFactory(7, 9);
Assert.Throws<ArgumentOutOfRangeException>((() => chunk.GetTile(8, 0)));
Assert.Throws<ArgumentOutOfRangeException>((() => chunk.GetTile(0, 8)));
}
[Test]
public void GetAllTilesNotEmpty()
{
var chunk = MapChunkFactory(7, 9);
chunk.SetTile(5, 4, new Tile(5, 7));
chunk.SetTile(3, 5, new Tile(1, 3));
var tiles = chunk.GetAllTiles().ToList();
Assert.That(tiles.Count, Is.EqualTo(2));
// Order is guaranteed to be row-major (because C# is), the Y value is contiguous in memory
Assert.That(tiles[0],
Is.EqualTo(new TileRef(new MapId(11),
new GridId(13),
new MapIndices(8 * 7 + 3, 8 * 9 + 5),
new Tile(1, 3))));
Assert.That(tiles[1],
Is.EqualTo(new TileRef(new MapId(11),
new GridId(13),
new MapIndices(8 * 7 + 5, 8 * 9 + 4),
new Tile(5, 7))));
}
[Test]
public void GetAllTilesEmpty()
{
var chunk = MapChunkFactory(7, 9);
chunk.SetTile(5, 4, new Tile(5, 7));
chunk.SetTile(3, 5, new Tile(1, 3));
var tiles = chunk.GetAllTiles(false).ToList();
Assert.That(tiles.Count, Is.EqualTo(8*8));
// Order is guaranteed to be row-major (because C# is), the Y value is contiguous in memory
Assert.That(tiles[8*3+5],
Is.EqualTo(new TileRef(new MapId(11),
new GridId(13),
new MapIndices(8 * 7 + 3, 8 * 9 + 5),
new Tile(1, 3))));
Assert.That(tiles[8*5+4],
Is.EqualTo(new TileRef(new MapId(11),
new GridId(13),
new MapIndices(8 * 7 + 5, 8 * 9 + 4),
new Tile(5, 7))));
}
[Test]
public void SetTileNotifiesGrid()
{
var mapGrid = new Mock<IMapGridInternal>();
mapGrid.SetupGet(f => f.CurTick).Returns(new GameTick(11));
mapGrid.SetupGet(f => f.ParentMapId).Returns(new MapId(11));
mapGrid.SetupGet(f => f.Index).Returns(new GridId(13));
mapGrid.Setup(f => f.NotifyTileChanged(It.Ref<TileRef>.IsAny, It.Ref<Tile>.IsAny)).Verifiable();
var chunk = new MapChunk(mapGrid.Object, 7, 9, 8);
chunk.SetTile(3, 5, new Tile(1, 3));
mapGrid.Verify(f => f.NotifyTileChanged(It.Ref<TileRef>.IsAny, It.Ref<Tile>.IsAny), Times.Once);
}
[Test]
public void SetTileDuplicateNotifiesOnce()
{
var mapGrid = new Mock<IMapGridInternal>();
mapGrid.SetupGet(f => f.CurTick).Returns(new GameTick(11));
mapGrid.SetupGet(f => f.ParentMapId).Returns(new MapId(11));
mapGrid.SetupGet(f => f.Index).Returns(new GridId(13));
mapGrid.Setup(f => f.NotifyTileChanged(It.Ref<TileRef>.IsAny, It.Ref<Tile>.IsAny)).Verifiable();
var chunk = new MapChunk(mapGrid.Object, 7, 9, 8);
chunk.SetTile(3, 5, new Tile(1, 3));
chunk.SetTile(3, 5, new Tile(1, 3));
mapGrid.Verify(f => f.NotifyTileChanged(It.Ref<TileRef>.IsAny, It.Ref<Tile>.IsAny), Times.Once);
}
[Test]
public void EnumerateTiles()
{
var chunk = MapChunkFactory(7, 9);
chunk.SetTile(5, 4, new Tile(5, 7));
chunk.SetTile(3, 5, new Tile(1, 3));
var tiles = new List<TileRef>();
foreach (var tileRef in ((IEnumerable)chunk))
{
tiles.Add((TileRef)tileRef);
}
Assert.That(tiles.Count, Is.EqualTo(2));
// Order is guaranteed to be row-major (because C# is), the Y value is contiguous in memory
Assert.That(tiles[0],
Is.EqualTo(new TileRef(new MapId(11),
new GridId(13),
new MapIndices(8 * 7 + 3, 8 * 9 + 5),
new Tile(1, 3))));
Assert.That(tiles[1],
Is.EqualTo(new TileRef(new MapId(11),
new GridId(13),
new MapIndices(8 * 7 + 5, 8 * 9 + 4),
new Tile(5, 7))));
}
[Test]
public void GridToChunkIndices()
{
// chunk indices are relative to the lowest coordinates of the chunk
// EX 8x8 chunk (0,0) occupies tiles 0 to 8 on each axis
// 8x8 chunk (-1,-1) occupies tiles -8 to -1 on each axis
var chunk = MapChunkFactory(-1, -1);
var indices = chunk.GridTileToChunkTile(new MapIndices(-3, -5));
// drawing this out helps a ton
// grid tile -1,-1 is chunk tile 7,7
// grid tile -8,-8 is chunk tile 0,0
Assert.That(indices, Is.EqualTo(new MapIndices(5, 3)));
}
[Test]
public void GetToString()
{
var chunk = MapChunkFactory(7, 9);
var result = chunk.ToString();
Assert.That(result, Is.EqualTo("Chunk {7,9}"));
}
[Test]
public void GetEmptySnapGrid()
{
var chunk = MapChunkFactory(7, 9);
Assert.That(chunk.GetSnapGridCell(0,0, SnapGridOffset.Center).ToList().Count, Is.EqualTo(0));
Assert.That(chunk.GetSnapGridCell(0, 0, SnapGridOffset.Edge).ToList().Count, Is.EqualTo(0));
}
[Test]
public void GetSnapGridThrowsOutOfRange()
{
var chunk = MapChunkFactory(7, 9);
Assert.Throws<ArgumentOutOfRangeException>((() => chunk.GetSnapGridCell(8,0, SnapGridOffset.Center).ToList()));
Assert.Throws<ArgumentOutOfRangeException>((() => chunk.GetSnapGridCell(0, 8, SnapGridOffset.Center).ToList()));
Assert.Throws<ArgumentOutOfRangeException>((() => chunk.GetSnapGridCell(8,0,SnapGridOffset.Edge).ToList()));
Assert.Throws<ArgumentOutOfRangeException>((() => chunk.GetSnapGridCell(0, 8, SnapGridOffset.Edge).ToList()));
}
[Test]
public void AddSnapGridCellCenter()
{
var chunk = MapChunkFactory(7, 9);
var snapGridComponent = new SnapGridComponent();
chunk.AddToSnapGridCell(3, 5, SnapGridOffset.Center, snapGridComponent);
chunk.AddToSnapGridCell(3, 5, SnapGridOffset.Edge, new SnapGridComponent());
chunk.AddToSnapGridCell(3, 6, SnapGridOffset.Center, new SnapGridComponent());
var result = chunk.GetSnapGridCell(3, 5, SnapGridOffset.Center).ToList();
Assert.That(result.Count, Is.EqualTo(1));
Assert.That(result[0], Is.EqualTo(snapGridComponent));
}
[Test]
public void AddSnapGridCellEdge()
{
var chunk = MapChunkFactory(7, 9);
var snapGridComponent = new SnapGridComponent();
chunk.AddToSnapGridCell(3, 5, SnapGridOffset.Edge, snapGridComponent);
chunk.AddToSnapGridCell(3, 5, SnapGridOffset.Center, new SnapGridComponent());
chunk.AddToSnapGridCell(3, 6, SnapGridOffset.Edge, new SnapGridComponent());
var result = chunk.GetSnapGridCell(3, 5, SnapGridOffset.Edge).ToList();
Assert.That(result.Count, Is.EqualTo(1));
Assert.That(result[0], Is.EqualTo(snapGridComponent));
}
[Test]
public void AddSnapGridThrowsOutOfRange()
{
var chunk = MapChunkFactory(7, 9);
Assert.Throws<ArgumentOutOfRangeException>((() => chunk.AddToSnapGridCell(8, 0, SnapGridOffset.Center, new SnapGridComponent())));
Assert.Throws<ArgumentOutOfRangeException>((() => chunk.AddToSnapGridCell(0, 8, SnapGridOffset.Center, new SnapGridComponent())));
Assert.Throws<ArgumentOutOfRangeException>((() => chunk.AddToSnapGridCell(8, 0, SnapGridOffset.Edge, new SnapGridComponent())));
Assert.Throws<ArgumentOutOfRangeException>((() => chunk.AddToSnapGridCell(0, 8, SnapGridOffset.Edge, new SnapGridComponent())));
}
[Test]
public void RemoveSnapGridCellCenter()
{
var chunk = MapChunkFactory(7, 9);
var snapGridComponent = new SnapGridComponent();
chunk.AddToSnapGridCell(3, 5, SnapGridOffset.Center, snapGridComponent);
chunk.AddToSnapGridCell(3, 5, SnapGridOffset.Edge, new SnapGridComponent());
chunk.AddToSnapGridCell(3, 6, SnapGridOffset.Center, new SnapGridComponent());
chunk.RemoveFromSnapGridCell(3, 5, SnapGridOffset.Center, snapGridComponent);
var result = chunk.GetSnapGridCell(3, 5, SnapGridOffset.Center).ToList();
Assert.That(result.Count, Is.EqualTo(0));
}
[Test]
public void RemoveSnapGridCellEdge()
{
var chunk = MapChunkFactory(7, 9);
var snapGridComponent = new SnapGridComponent();
chunk.AddToSnapGridCell(3, 5, SnapGridOffset.Edge, snapGridComponent);
chunk.AddToSnapGridCell(3, 5, SnapGridOffset.Center, new SnapGridComponent());
chunk.AddToSnapGridCell(3, 6, SnapGridOffset.Edge, new SnapGridComponent());
chunk.RemoveFromSnapGridCell(3, 5, SnapGridOffset.Edge, snapGridComponent);
var result = chunk.GetSnapGridCell(3, 5, SnapGridOffset.Edge).ToList();
Assert.That(result.Count, Is.EqualTo(0));
}
[Test]
public void RemoveSnapGridThrowsOutOfRange()
{
var chunk = MapChunkFactory(7, 9);
Assert.Throws<ArgumentOutOfRangeException>((() => chunk.RemoveFromSnapGridCell(8, 0, SnapGridOffset.Center, new SnapGridComponent())));
Assert.Throws<ArgumentOutOfRangeException>((() => chunk.RemoveFromSnapGridCell(0, 8, SnapGridOffset.Center, new SnapGridComponent())));
Assert.Throws<ArgumentOutOfRangeException>((() => chunk.RemoveFromSnapGridCell(8, 0, SnapGridOffset.Edge, new SnapGridComponent())));
Assert.Throws<ArgumentOutOfRangeException>((() => chunk.RemoveFromSnapGridCell(0, 8, SnapGridOffset.Edge, new SnapGridComponent())));
}
[Test]
public void BoundsExpandWhenTileAdded()
{
var chunk = MapChunkFactory(7, 9);
chunk.SetTile(3, 5, new Tile(1));
chunk.SetTile(5, 7, new Tile(1));
var bounds = chunk.CalcLocalBounds();
Assert.That(bounds.Left, Is.EqualTo(3));
Assert.That(bounds.Bottom, Is.EqualTo(5));
Assert.That(bounds.Right, Is.EqualTo(6));
Assert.That(bounds.Top, Is.EqualTo(8));
}
[Test]
public void BoundsContractWhenTileRemovedBL()
{
var chunk = MapChunkFactory(7, 9);
chunk.SetTile(3, 5, new Tile(1));
chunk.SetTile(5, 7, new Tile(1));
chunk.SetTile(3, 5, Tile.Empty);
var bounds = chunk.CalcLocalBounds();
Assert.That(bounds.Left, Is.EqualTo(5));
Assert.That(bounds.Bottom, Is.EqualTo(7));
Assert.That(bounds.Right, Is.EqualTo(6));
Assert.That(bounds.Top, Is.EqualTo(8));
}
[Test]
public void BoundsContractWhenTileRemovedTR()
{
var chunk = MapChunkFactory(7, 9);
chunk.SetTile(3, 5, new Tile(1));
chunk.SetTile(5, 7, new Tile(1));
chunk.SetTile(5, 7, Tile.Empty);
var bounds = chunk.CalcLocalBounds();
Assert.That(bounds.Left, Is.EqualTo(3));
Assert.That(bounds.Bottom, Is.EqualTo(5));
Assert.That(bounds.Right, Is.EqualTo(4));
Assert.That(bounds.Top, Is.EqualTo(6));
}
public IMapChunkInternal MapChunkFactory(int xChunkIndex, int yChunkIndex)
{
var mapGrid = new Mock<IMapGridInternal>();
mapGrid.SetupGet(f=>f.CurTick).Returns(new GameTick(11));
mapGrid.SetupGet(f => f.ParentMapId).Returns(new MapId(11));
mapGrid.SetupGet(f => f.Index).Returns(new GridId(13));
return new MapChunk(mapGrid.Object, xChunkIndex, yChunkIndex, 8);
}
}
}