using System.IO;
using System.Linq;
using UnitTestSharp;
using Vellum;
namespace Annulus.Vellum.UnitTests
{
public class HexGridConverterTests : TestFixture
{
public const int Sentinel = -99;
public static SaveSession Session()
{
return SaveConverters.For(typeof(HexGridConverterTests).Assembly).CreateSession();
}
///
/// Builds a grid whose every cell holds its place in the order of the grid plus one.
///
public static HexGrid Numbered(HexOrientation orientation, int rows, int columns)
{
var returnMe = new HexGrid(orientation, rows, columns, Sentinel);
for (int i = 0; i < returnMe.Count; ++i)
{
returnMe[returnMe.IndexAt(i)] = i + 1;
}
return returnMe;
}
public static HexGrid Loaded(SaveNode node)
{
return (HexGrid)Session().FromNode(node, typeof(HexGrid));
}
public static bool SameGrid(HexGrid expected, HexGrid actual)
{
if (expected.Orientation != actual.Orientation || expected.Rows != actual.Rows
|| expected.Columns != actual.Columns || expected.OutOfBounds != actual.OutOfBounds)
{
return false;
}
for (int i = 0; i < expected.Count; ++i)
{
HexIndex index = expected.IndexAt(i);
if (expected[index] != actual[index])
{
return false;
}
}
return true;
}
public class WriteTests : TestFixture
{
public void SavesTheShapeAndWhatLiesOutside()
{
SaveNode node = Session().ToNode(Numbered(HexOrientation.FlatTop, 2, 3), typeof(HexGrid));
CheckEqual(SaveNode.Kinds.Table, node.Kind);
CheckEqual("2", node.RequireEntry(HexGridConverter.RowsKey).Text);
CheckEqual("3", node.RequireEntry(HexGridConverter.ColumnsKey).Text);
CheckEqual("-99", node.RequireEntry(HexGridConverter.OutOfBoundsKey).Text);
CheckEqual("FlatTop", node.RequireEntry(HexGridConverter.OrientationKey).Text);
}
public void SavesTheCellsInTheOrderOfTheGrid()
{
SaveNode node = Session().ToNode(Numbered(HexOrientation.PointyTop, 2, 3), typeof(HexGrid));
CheckEqual(new[] { "1", "2", "3", "4", "5", "6" },
node.RequireEntry(HexGridConverter.CellsKey).Items.Select(item => item.Text).ToArray());
}
public void AnEmptyGrid_SavesNoCells()
{
var grid = new HexGrid(HexOrientation.PointyTop, 0, 5, Sentinel);
SaveNode node = Session().ToNode(grid, typeof(HexGrid));
CheckEqual(0, node.RequireEntry(HexGridConverter.CellsKey).Items.Count);
}
}
public class ReadTests : TestFixture
{
public void EitherOrientation_RoundTrips()
{
foreach (HexOrientation orientation in new[] { HexOrientation.PointyTop, HexOrientation.FlatTop })
{
HexGrid grid = Numbered(orientation, 3, 4);
CheckTrue(SameGrid(grid, Loaded(Session().ToNode(grid, typeof(HexGrid)))));
}
}
public void EachCellKeepsItsHex()
{
HexGrid grid = Numbered(HexOrientation.PointyTop, 3, 4);
HexGrid loaded = Loaded(Session().ToNode(grid, typeof(HexGrid)));
CheckEqual(grid[new HexIndex(2, 1)], loaded[new HexIndex(2, 1)]);
CheckEqual(Sentinel, loaded[new HexIndex(-20, 0)]);
}
public void ThroughLuaText_RoundTrips()
{
HexGrid grid = Numbered(HexOrientation.FlatTop, 3, 2);
SaveNode save = SaveNode.NewTable();
save.Entries["grid"] = Session().ToNode(grid, typeof(HexGrid));
SaveNode read = LuaSaveFormat.Parse(LuaSaveFormat.Format(save));
CheckTrue(SameGrid(grid, Loaded(read.RequireEntry("grid"))));
}
public void AnEmptyGrid_RoundTrips()
{
var grid = new HexGrid(HexOrientation.PointyTop, 4, 0, Sentinel);
CheckTrue(SameGrid(grid, Loaded(Session().ToNode(grid, typeof(HexGrid)))));
}
public void ReferenceCells_RoundTripIncludingNull()
{
var grid = new HexGrid(HexOrientation.PointyTop, 1, 3, "outside");
grid[new HexIndex(0, 0)] = "a";
grid[new HexIndex(2, 0)] = "c";
SaveSession session = Session();
var loaded = (HexGrid)session.FromNode(
session.ToNode(grid, typeof(HexGrid)), typeof(HexGrid));
CheckEqual("a", loaded[new HexIndex(0, 0)]);
CheckNull(loaded[new HexIndex(1, 0)]);
CheckEqual("c", loaded[new HexIndex(2, 0)]);
CheckEqual("outside", loaded.OutOfBounds);
}
public void TooFewCells_Throws()
{
SaveNode node = Session().ToNode(Numbered(HexOrientation.PointyTop, 2, 3), typeof(HexGrid));
node.RequireEntry(HexGridConverter.CellsKey).Items.RemoveAt(0);
CheckThrow(typeof(InvalidDataException));
Loaded(node);
}
public void TooManyCells_Throws()
{
SaveNode node = Session().ToNode(Numbered(HexOrientation.PointyTop, 2, 3), typeof(HexGrid));
node.RequireEntry(HexGridConverter.CellsKey).Items.Add(SaveNode.OfText("7"));
CheckThrow(typeof(InvalidDataException));
Loaded(node);
}
public void NegativeRows_Throws()
{
SaveNode node = Session().ToNode(Numbered(HexOrientation.PointyTop, 2, 3), typeof(HexGrid));
node.Entries[HexGridConverter.RowsKey] = SaveNode.OfText("-2");
node.Entries[HexGridConverter.ColumnsKey] = SaveNode.OfText("-3");
CheckThrow(typeof(InvalidDataException));
Loaded(node);
}
public void ADamagedHugeShape_Throws()
{
SaveNode node = Session().ToNode(Numbered(HexOrientation.PointyTop, 2, 3), typeof(HexGrid));
node.Entries[HexGridConverter.RowsKey] = SaveNode.OfText("100000");
node.Entries[HexGridConverter.ColumnsKey] = SaveNode.OfText("100000");
CheckThrow(typeof(InvalidDataException));
Loaded(node);
}
public void MissingCells_Throws()
{
SaveNode node = Session().ToNode(Numbered(HexOrientation.PointyTop, 2, 3), typeof(HexGrid));
node.Entries.Remove(HexGridConverter.CellsKey);
CheckThrow(typeof(InvalidDataException));
Loaded(node);
}
public void ABadCell_LoadsAsDefaultAndIsRecordedAsAnIssue()
{
SaveNode node = Session().ToNode(Numbered(HexOrientation.PointyTop, 2, 2), typeof(HexGrid));
node.RequireEntry(HexGridConverter.CellsKey).Items[1] = SaveNode.OfText("not a number");
SaveSession session = Session();
var loaded = (HexGrid)session.FromNode(node, typeof(HexGrid));
CheckEqual(1, loaded[loaded.IndexAt(0)]);
CheckEqual(0, loaded[loaded.IndexAt(1)]);
CheckEqual(3, loaded[loaded.IndexAt(2)]);
CheckEqual(1, session.Sandbox.Issues.Count);
}
public void NodeThatIsNotATable_Throws()
{
CheckThrow(typeof(InvalidDataException));
Loaded(SaveNode.OfText("1"));
}
public void NullForAGrid_IsNull()
{
CheckNull(Session().FromNode(SaveNode.Null, typeof(HexGrid)));
}
}
public class TryListChildrenTests : TestFixture
{
public void ListsTheOutOfBoundsValueThenEachCellAsTheCellType()
{
SaveNode node = Session().ToNode(Numbered(HexOrientation.PointyTop, 1, 2), typeof(HexGrid));
var children = new ChildList();
CheckTrue(new HexGridConverter().TryListChildren(node, children));
CheckEqual(3, children.Count);
CheckTrue(ReferenceEquals(node.RequireEntry(HexGridConverter.OutOfBoundsKey),
children.NodeAt(0)));
CheckTrue(ReferenceEquals(node.RequireEntry(HexGridConverter.CellsKey).Items[1],
children.NodeAt(2)));
CheckEqual(typeof(int), children.TypeAt(0));
CheckEqual(typeof(int), children.TypeAt(2));
}
public void NodeWithoutCells_ReturnsFalse()
{
SaveNode node = Session().ToNode(Numbered(HexOrientation.PointyTop, 1, 2), typeof(HexGrid));
node.Entries.Remove(HexGridConverter.CellsKey);
CheckFalse(new HexGridConverter().TryListChildren(node, new ChildList()));
}
public void NodeWithoutOutOfBounds_ReturnsFalse()
{
SaveNode node = Session().ToNode(Numbered(HexOrientation.PointyTop, 1, 2), typeof(HexGrid));
node.Entries.Remove(HexGridConverter.OutOfBoundsKey);
CheckFalse(new HexGridConverter().TryListChildren(node, new ChildList()));
}
public void CellsThatAreNotAList_ReturnFalse()
{
SaveNode node = Session().ToNode(Numbered(HexOrientation.PointyTop, 1, 2), typeof(HexGrid));
node.Entries[HexGridConverter.CellsKey] = SaveNode.OfText("3");
CheckFalse(new HexGridConverter().TryListChildren(node, new ChildList()));
}
public void NodeThatIsNotATable_ReturnsFalse()
{
CheckFalse(new HexGridConverter().TryListChildren(SaveNode.OfText("3"), new ChildList()));
}
}
}
}