Files
h-school/tests/HSchool.Simulation.Tests/SchoolRegistryTests.cs
T

180 lines
5.2 KiB
C#

namespace HSchool.Simulation.Tests;
public class SchoolRegistryTests
{
private static readonly DateTime Start = new(2012, 4, 3, 6, 0, 0, DateTimeKind.Utc);
private static SchoolRegistry NewRegistry(int maxSchools = 6) =>
new(new SimulationOptions { MaxSchools = maxSchools, TickRate = 20, GameMinutesPerRealSecond = 5 });
[Fact]
public void NewRegistry_IsEmpty()
{
using var registry = NewRegistry();
Assert.Equal(0, registry.Count);
Assert.Equal(6, registry.MaxSchools);
Assert.False(registry.IsFull);
}
[Fact]
public void Create_AddsASchoolAtTheGivenStartDate()
{
using var registry = NewRegistry();
var result = registry.Create("Гимназия №1", Start);
Assert.True(result.Succeeded);
Assert.Equal("Гимназия №1", result.School!.Name);
Assert.Equal(Start, result.School.Clock.Time);
// A new school starts living straight away; only the pause button stops it.
Assert.True(result.School.Clock.IsRunning);
Assert.Equal(1, registry.Count);
}
[Fact]
public void Create_BeyondTheLimit_Fails()
{
using var registry = NewRegistry(maxSchools: 2);
registry.Create("Первая", Start);
registry.Create("Вторая", Start);
var result = registry.Create("Третья", Start);
Assert.False(result.Succeeded);
Assert.Equal(SchoolCreationError.LimitReached, result.Error);
Assert.True(registry.IsFull);
Assert.Equal(2, registry.Count);
}
[Fact]
public void Delete_FreesASlot()
{
using var registry = NewRegistry(maxSchools: 1);
var first = registry.Create("Первая", Start).School!;
Assert.False(registry.Create("Вторая", Start).Succeeded);
Assert.True(registry.Delete(first.Id));
Assert.True(registry.Create("Вторая", Start).Succeeded);
}
[Fact]
public void Delete_UnknownId_ReportsFailure()
{
using var registry = NewRegistry();
Assert.False(registry.Delete(42));
}
[Fact]
public void Ids_AreNotReusedAfterDeletion()
{
using var registry = NewRegistry();
var first = registry.Create("Первая", Start).School!;
registry.Delete(first.Id);
var second = registry.Create("Вторая", Start).School!;
Assert.NotEqual(first.Id, second.Id);
Assert.Null(registry.Find(first.Id));
}
[Theory]
[InlineData("")]
[InlineData(" ")]
[InlineData("\t\n")]
public void Create_RejectsBlankNames(string name)
{
using var registry = NewRegistry();
Assert.Equal(SchoolCreationError.InvalidName, registry.Create(name, Start).Error);
}
[Fact]
public void Create_RejectsOverlongNames()
{
using var registry = NewRegistry();
var result = registry.Create(new string('ш', School.MaxNameLength + 1), Start);
Assert.Equal(SchoolCreationError.InvalidName, result.Error);
}
[Fact]
public void Create_TrimsAndStripsControlCharacters()
{
using var registry = NewRegistry();
var result = registry.Create(" Лицей ", Start);
Assert.Equal("Лицей", result.School!.Name);
}
[Fact]
public void Create_RejectsStartDatesOutsideTheSupportedRange()
{
using var registry = NewRegistry();
var result = registry.Create("Школа", new DateTime(1500, 1, 1, 0, 0, 0, DateTimeKind.Utc));
Assert.Equal(SchoolCreationError.InvalidStartDate, result.Error);
}
[Fact]
public void Tick_AdvancesOnlyRunningSchools()
{
using var registry = NewRegistry();
var running = registry.Create("Идёт", Start).School!;
var paused = registry.Create("Стоит", Start).School!;
paused.Clock.IsRunning = false;
for (var i = 0; i < 20; i++)
{
registry.Tick();
}
Assert.Equal(Start.AddMinutes(5), running.Clock.Time);
Assert.Equal(Start, paused.Clock.Time);
}
[Fact]
public void SuggestName_NeverRepeatsAnExistingName()
{
using var registry = NewRegistry(maxSchools: 20);
for (var i = 0; i < 20; i++)
{
var suggestion = registry.SuggestName();
Assert.True(registry.Create(suggestion, Start).Succeeded, $"\"{suggestion}\" was rejected.");
}
var names = registry.Schools.Select(school => school.Name).ToArray();
Assert.Equal(names.Length, names.Distinct(StringComparer.OrdinalIgnoreCase).Count());
}
[Fact]
public void SuggestedNames_FitTheNameLimit()
{
var generator = new SchoolNameGenerator(new Random(1234));
for (var i = 0; i < 200; i++)
{
var name = generator.Next([]);
Assert.InRange(name.Length, 1, School.MaxNameLength);
}
}
[Fact]
public void Dispose_DropsEverySchool()
{
var registry = NewRegistry();
registry.Create("Школа", Start);
registry.Dispose();
Assert.Equal(0, registry.Count);
}
}