- Introduced a new project for timetable planning, dependent on HSchool.Content. - Updated documentation to reflect the addition of timetable planning and its dependencies. - Added tests for timetable planning to ensure deterministic behavior with the same staff and map. - Revised architecture documentation to include the new HSchool.Schedule component and its interactions.
113 lines
3.4 KiB
C#
113 lines
3.4 KiB
C#
using HSchool.Content;
|
|
|
|
namespace HSchool.Schedule.Tests;
|
|
|
|
internal static class PackDocuments
|
|
{
|
|
public static IReadOnlyList<ContentDocument> FromDirectory(string packId, string packRoot)
|
|
{
|
|
var documents = new List<ContentDocument>();
|
|
foreach (var path in Directory.EnumerateFiles(packRoot, "*.*", SearchOption.AllDirectories))
|
|
{
|
|
if (!path.EndsWith(".jsonc", StringComparison.OrdinalIgnoreCase)
|
|
&& !path.EndsWith(".json", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var relative = Path.GetRelativePath(packRoot, path).Replace('\\', '/');
|
|
documents.Add(new ContentDocument(packId, relative, File.ReadAllText(path)));
|
|
}
|
|
|
|
return documents;
|
|
}
|
|
}
|
|
|
|
internal static class Fixtures
|
|
{
|
|
public static DefCatalog Catalog()
|
|
{
|
|
var root = Path.Combine(AppContext.BaseDirectory, "vanilla");
|
|
return new CatalogLoader().Load(
|
|
[CatalogLoader.CorePackId],
|
|
PackDocuments.FromDirectory(CatalogLoader.CorePackId, root));
|
|
}
|
|
|
|
public static MapLayout ClassroomsAndGym(int classes, int desks = 16)
|
|
{
|
|
var rooms = new List<RoomNode>(classes + 1);
|
|
for (var i = 0; i < classes; i++)
|
|
{
|
|
rooms.Add(Classroom(i, desks));
|
|
}
|
|
|
|
rooms.Add(new RoomNode
|
|
{
|
|
Id = "gym-hall",
|
|
Def = "GymHall",
|
|
Building = "gym",
|
|
Floor = "gym-floor",
|
|
Slots = [new SlotFill { Key = "benches", Thing = "Bench", Count = 4 }],
|
|
});
|
|
|
|
return new MapLayout { Rooms = rooms };
|
|
}
|
|
|
|
public static MapLayout ClassroomAndLab(int desks = 16, int computers = 12)
|
|
{
|
|
return new MapLayout
|
|
{
|
|
Rooms =
|
|
[
|
|
Classroom(0, desks),
|
|
new RoomNode
|
|
{
|
|
Id = "computer-lab",
|
|
Def = "ComputerLab",
|
|
Building = "main",
|
|
Floor = "floor-1",
|
|
Slots =
|
|
[
|
|
new SlotFill { Key = "teacherDesk", Thing = "Desk", Count = 1 },
|
|
new SlotFill { Key = "teacherChair", Thing = "Chair", Count = 1 },
|
|
new SlotFill { Key = "computers", Thing = "Computer", Count = computers },
|
|
],
|
|
},
|
|
],
|
|
};
|
|
}
|
|
|
|
public static PlannerClass Class(int index, int year, int pupils, string letter = "A") =>
|
|
new($"y{year}{letter}", year, letter, $"classroom-{index:00}", pupils);
|
|
|
|
public static PlannerTeacher Teacher(string id, params string[] subjects) =>
|
|
new(id, subjects);
|
|
|
|
public static RoomNode Classroom(int index, int desks) =>
|
|
new()
|
|
{
|
|
Id = $"classroom-{index:00}",
|
|
Def = "Classroom",
|
|
Building = "main",
|
|
Floor = "floor-1",
|
|
Label = $"{101 + index}",
|
|
Seats = desks,
|
|
};
|
|
|
|
public static string RepoRoot()
|
|
{
|
|
var dir = new DirectoryInfo(AppContext.BaseDirectory);
|
|
while (dir is not null && !File.Exists(Path.Combine(dir.FullName, "h-school.sln")))
|
|
{
|
|
dir = dir.Parent;
|
|
}
|
|
|
|
if (dir is null)
|
|
{
|
|
throw new InvalidOperationException("Could not find h-school.sln from the test output directory.");
|
|
}
|
|
|
|
return dir.FullName;
|
|
}
|
|
}
|