Files
h-school/tests/HSchool.People.Tests/RosterFingerprint.cs
T
Leonid Pershin e5a0ae5b9d
ci / server (push) Failing after 3m43s
ci / client (push) Successful in 14s
Enhance staffing management with uncovered teacher tracking
- Updated `protocol.md` to clarify the concept of uncovered subjects and the number of additional teachers required.
- Introduced `teachersShort` property in the `StaffingSubject` interface to indicate how many more teachers are needed for a subject.
- Enhanced localization strings to reflect the new uncovered teacher information in both English and Russian.
- Updated the management panel UI to display the number of teachers short for each uncovered subject.
- Revised the `Uncovered` method in the staffing logic to return detailed information about uncovered subjects, including the shortfall of teachers.
- Added tests to validate the new uncovered teacher tracking functionality and ensure accurate reporting in the staffing API.
- Marked related tasks as complete in the documentation for the golden fixtures phase.
2026-08-19 23:53:37 +03:00

79 lines
2.7 KiB
C#

namespace HSchool.People.Tests;
/// <summary>
/// One line per class and person, sorted, so a generator change shows up as the first
/// mismatched line instead of "the snapshots differ".
/// </summary>
internal static class RosterFingerprint
{
public static string Format(Roster roster, int seed, string nameSet, string native)
{
var lines = new List<string>
{
$"# seed={seed} nameset={nameSet} native={native} people={roster.People.Count} classes={roster.Classes.Count}",
};
foreach (var schoolClass in roster.Classes.OrderBy(row => row.Id, StringComparer.Ordinal))
{
var pupils = string.Join(',', schoolClass.PupilIds.Order(StringComparer.Ordinal));
lines.Add(
$"class {schoolClass.Id} year={schoolClass.Year} letter={schoolClass.Letter} room={schoolClass.RoomId} capacity={schoolClass.Capacity} pupils={pupils}");
}
foreach (var person in roster.People.OrderBy(row => row.Id, StringComparer.Ordinal))
{
lines.Add(PersonLine(person));
}
return string.Join('\n', lines) + '\n';
}
public static void AssertEqual(string expected, string actual)
{
var left = expected.Replace("\r\n", "\n", StringComparison.Ordinal).Split('\n');
var right = actual.Replace("\r\n", "\n", StringComparison.Ordinal).Split('\n');
var count = Math.Min(left.Length, right.Length);
for (var i = 0; i < count; i++)
{
if (!string.Equals(left[i], right[i], StringComparison.Ordinal))
{
Assert.Fail($"first mismatch at line {i + 1}\nexpected: {left[i]}\nactual: {right[i]}");
}
}
if (left.Length != right.Length)
{
Assert.Fail($"line count {left.Length} vs {right.Length}");
}
}
private static string PersonLine(Person person)
{
var roles = string.Join(',', Roles(person));
var traits = string.Join(',', person.Traits.Order(StringComparer.Ordinal));
var skills = string.Join(
',',
person.Skills.OrderBy(pair => pair.Key, StringComparer.Ordinal).Select(pair => $"{pair.Key}={pair.Value}"));
return
$"person {person.Id} {person.Name.Full} female={person.Female} roles={roles} class={person.ClassId ?? "-"} born={person.BirthDate:yyyy-MM-dd} traits={traits} skills={skills}";
}
private static IEnumerable<string> Roles(Person person)
{
if (person.IsStudent)
{
yield return "student";
}
if (person.IsStaff)
{
yield return "staff";
}
if (person.IsParent)
{
yield return "parent";
}
}
}