feat(CS-P1): Castle Siege phase state machine (in-memory, time-injected) + tests
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
// <copyright file="CastleSiegeContextTest.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.Tests.CastleSiege;
|
||||
|
||||
using MUnique.OpenMU.GameLogic.CastleSiege;
|
||||
|
||||
/// <summary>
|
||||
/// Tests for the Castle Siege phase state machine (time-driven, injected clock).
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class CastleSiegeContextTest
|
||||
{
|
||||
private static readonly DateTime T0 = new(2026, 1, 1, 12, 0, 0, DateTimeKind.Utc);
|
||||
|
||||
/// <summary>Tests that a fresh context starts in the ownership (resting) phase.</summary>
|
||||
[Test]
|
||||
public void StartsInOwnership()
|
||||
{
|
||||
var ctx = new CastleSiegeContext(Config());
|
||||
Assert.That(ctx.Phase, Is.EqualTo(CastleSiegePhase.Ownership));
|
||||
}
|
||||
|
||||
/// <summary>Tests that force-starting moves the state machine into registration.</summary>
|
||||
[Test]
|
||||
public async Task ForceStartMovesToRegistrationAsync()
|
||||
{
|
||||
var ctx = new CastleSiegeContext(Config());
|
||||
await ctx.ForceStartRegistrationAsync(T0);
|
||||
Assert.That(ctx.Phase, Is.EqualTo(CastleSiegePhase.Registration));
|
||||
}
|
||||
|
||||
/// <summary>Tests that registration advances to preparation once its duration elapses.</summary>
|
||||
[Test]
|
||||
public async Task RegistrationAdvancesToPreparationAfterDurationAsync()
|
||||
{
|
||||
var ctx = new CastleSiegeContext(Config());
|
||||
await ctx.ForceStartRegistrationAsync(T0);
|
||||
await ctx.TickAsync(T0.AddMinutes(4)); // still within registration
|
||||
Assert.That(ctx.Phase, Is.EqualTo(CastleSiegePhase.Registration));
|
||||
await ctx.TickAsync(T0.AddMinutes(5)); // registration duration elapsed
|
||||
Assert.That(ctx.Phase, Is.EqualTo(CastleSiegePhase.Preparation));
|
||||
}
|
||||
|
||||
/// <summary>Tests a full cycle: registration -> preparation -> siege -> settlement -> ownership.</summary>
|
||||
[Test]
|
||||
public async Task FullCycleReturnsToOwnershipAsync()
|
||||
{
|
||||
var ctx = new CastleSiegeContext(Config());
|
||||
await ctx.ForceStartRegistrationAsync(T0);
|
||||
await ctx.TickAsync(T0.AddMinutes(5)); // -> Preparation
|
||||
await ctx.TickAsync(T0.AddMinutes(7)); // +2 prep -> Siege
|
||||
Assert.That(ctx.Phase, Is.EqualTo(CastleSiegePhase.Siege));
|
||||
await ctx.TickAsync(T0.AddMinutes(17)); // +10 siege -> Settlement
|
||||
await ctx.TickAsync(T0.AddMinutes(17)); // Settlement -> Ownership
|
||||
Assert.That(ctx.Phase, Is.EqualTo(CastleSiegePhase.Ownership));
|
||||
}
|
||||
|
||||
/// <summary>Tests that guilds can be registered (by name) during the registration phase.</summary>
|
||||
[Test]
|
||||
public async Task RegisterGuildCollectsNamesDuringRegistrationAsync()
|
||||
{
|
||||
var ctx = new CastleSiegeContext(Config());
|
||||
await ctx.ForceStartRegistrationAsync(T0);
|
||||
ctx.RegisterGuild("Attackers");
|
||||
Assert.That(ctx.RegisteredGuilds, Does.Contain("Attackers"));
|
||||
}
|
||||
|
||||
private static CastleSiegeConfiguration Config() => new()
|
||||
{
|
||||
RegistrationDuration = TimeSpan.FromMinutes(5),
|
||||
PreparationDuration = TimeSpan.FromMinutes(2),
|
||||
SiegeDuration = TimeSpan.FromMinutes(10),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user