175 lines
6.4 KiB
C#
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,
|
|
};
|
|
}
|
|
}
|