Files
h-school/tests/HSchool.Content.Tests/MapValidationTests.cs
T

175 lines
6.4 KiB
C#

namespace HSchool.Content.Tests;
public class MapValidationTests
{
private readonly CatalogLoader _loader = new();
[Fact]
public void ConnectedMap_WithAnEmptyRoom_IsValid()
{
var (catalog, map) = MiniSchool(fillOffice: false);
MapValidator.Validate(map, catalog);
Assert.Empty(map.Rooms.Single(room => room.Id == "office").Slots);
Assert.Equal(["Principal"], catalog.PositionsFor(DefKind.Room, "Office"));
}
[Fact]
public void AbstractDef_CannotBePlacedOnTheMap()
{
var catalog = _loader.Load(
[CatalogLoader.CorePackId],
MiniDefs(abstractYard: true));
var map = MiniMap();
var ex = Assert.Throws<MapValidationException>(() => MapValidator.Validate(map, catalog));
Assert.Contains("Abstract", ex.Message);
}
[Fact]
public void UnknownDef_IsRejected()
{
var catalog = _loader.Load([CatalogLoader.CorePackId], MiniDefs());
var map = MiniMap(officeDef: "MissingOffice");
var ex = Assert.Throws<MapValidationException>(() => MapValidator.Validate(map, catalog));
Assert.Contains("Unknown", ex.Message);
}
[Fact]
public void EdgeToNowhere_IsRejected()
{
var (catalog, map) = MiniSchool(extraLink: new MapLink { A = "office", B = "ghost" });
var ex = Assert.Throws<MapValidationException>(() => MapValidator.Validate(map, catalog));
Assert.Contains("unknown node", ex.Message);
}
[Fact]
public void IsolatedNode_IsRejected()
{
var catalog = _loader.Load([CatalogLoader.CorePackId], MiniDefs());
var map = MiniMap(includeOfficeLink: false);
var ex = Assert.Throws<MapValidationException>(() => MapValidator.Validate(map, catalog));
Assert.Contains("isolated", ex.Message, StringComparison.OrdinalIgnoreCase);
}
[Fact]
public void DisconnectedGraph_IsRejected()
{
var catalog = _loader.Load([CatalogLoader.CorePackId], MiniDefs());
var map = new MapLayout
{
Territory = new TerritoryNode { Id = "yard", Def = "Yard" },
Buildings = [new BuildingNode { Id = "main", Def = "Main" }],
Floors = [new FloorNode { Id = "floor-1", Def = "Floor", Building = "main" }],
Rooms =
[
new RoomNode { Id = "office", Def = "Office", Building = "main", Floor = "floor-1" },
new RoomNode { Id = "a", Def = "Office", Building = "main", Floor = "floor-1" },
new RoomNode { Id = "b", Def = "Office", Building = "main", Floor = "floor-1" },
],
Links =
[
new MapLink { A = "yard", B = "office" },
new MapLink { A = "a", B = "b" },
],
};
var ex = Assert.Throws<MapValidationException>(() => MapValidator.Validate(map, catalog));
Assert.Contains("not connected", ex.Message);
}
[Fact]
public void OneRoomWithoutAYard_IsRejected()
{
var catalog = _loader.Load([CatalogLoader.CorePackId], MiniDefs());
var map = new MapLayout
{
Buildings = [new BuildingNode { Id = "main", Def = "Main" }],
Floors = [new FloorNode { Id = "floor-1", Def = "Floor", Building = "main" }],
Rooms = [new RoomNode { Id = "office", Def = "Office", Building = "main", Floor = "floor-1" }],
Links = [new MapLink { A = "office", B = "office" }],
};
var ex = Assert.Throws<MapValidationException>(() => MapValidator.Validate(map, catalog));
Assert.Contains("no territory", ex.Message);
}
[Fact]
public void MapWithNoRooms_IsRejected()
{
var catalog = _loader.Load([CatalogLoader.CorePackId], MiniDefs());
var map = new MapLayout
{
Territory = new TerritoryNode { Id = "yard", Def = "Yard" },
};
var ex = Assert.Throws<MapValidationException>(() => MapValidator.Validate(map, catalog));
Assert.Contains("at least one room", ex.Message);
}
private (DefCatalog Catalog, MapLayout Map) MiniSchool(bool fillOffice = true, MapLink? extraLink = null)
{
var catalog = _loader.Load([CatalogLoader.CorePackId], MiniDefs());
var map = MiniMap(fillOffice: fillOffice, extraLink: extraLink);
return (catalog, map);
}
private static List<ContentDocument> MiniDefs(bool abstractYard = false) =>
[
PackDocuments.Def(CatalogLoader.CorePackId, "actions", "sit", """{ "defName": "Sit" }"""),
PackDocuments.Def(CatalogLoader.CorePackId, "things", "chair", """{ "defName": "Chair", "actions": ["Sit"] }"""),
PackDocuments.Def(CatalogLoader.CorePackId, "positions", "principal", """{ "defName": "Principal" }"""),
PackDocuments.Def(
CatalogLoader.CorePackId,
"territories",
"yard",
abstractYard ? """{ "defName": "Yard", "abstract": true }""" : """{ "defName": "Yard" }"""),
PackDocuments.Def(CatalogLoader.CorePackId, "buildings", "main", """{ "defName": "Main" }"""),
PackDocuments.Def(CatalogLoader.CorePackId, "floors", "floor", """{ "defName": "Floor" }"""),
PackDocuments.Def(
CatalogLoader.CorePackId,
"rooms",
"office",
"""{ "defName": "Office", "slots": [{ "key": "seat", "thing": "Chair" }], "positions": ["Principal"] }"""),
];
private static MapLayout MiniMap(
bool fillOffice = false,
bool includeOfficeLink = true,
string officeDef = "Office",
MapLink? extraLink = null)
{
var links = new List<MapLink>();
if (includeOfficeLink)
{
links.Add(new MapLink { A = "yard", B = "office" });
}
if (extraLink is not null)
{
links.Add(extraLink);
}
return new MapLayout
{
Territory = new TerritoryNode { Id = "yard", Def = "Yard" },
Buildings = [new BuildingNode { Id = "main", Def = "Main" }],
Floors = [new FloorNode { Id = "floor-1", Def = "Floor", Building = "main" }],
Rooms =
[
new RoomNode
{
Id = "office",
Def = officeDef,
Building = "main",
Floor = "floor-1",
Slots = fillOffice ? [new SlotFill { Key = "seat", Thing = "Chair" }] : [],
},
],
Links = links,
};
}
}