180 lines
5.2 KiB
C#
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);
|
|
}
|
|
}
|