146 lines
4.3 KiB
C#
146 lines
4.3 KiB
C#
using FluentAssertions;
|
|
using Game.Blackjack;
|
|
using OECS;
|
|
using OECS.PlayTest;
|
|
using Xunit;
|
|
using Xunit.Abstractions;
|
|
|
|
namespace Game.Blackjack.Tests;
|
|
|
|
/// <summary>
|
|
/// Baseline snapshot and log tests for Blackjack.
|
|
/// Captures the world state as text and R3 change logs so they can be
|
|
/// reviewed manually and compared across changes.
|
|
/// </summary>
|
|
public class SnapshotTests
|
|
{
|
|
private readonly ITestOutputHelper _output;
|
|
|
|
public SnapshotTests(ITestOutputHelper output)
|
|
{
|
|
_output = output;
|
|
}
|
|
|
|
[Fact]
|
|
public void Snapshot_InitialState()
|
|
{
|
|
var (world, _) = TestHelpers.SetupGame();
|
|
|
|
var snapshot = TestHelpers.SnapshotWorld(world);
|
|
_output.WriteLine(snapshot);
|
|
|
|
snapshot.Should().Contain("Phase: Betting");
|
|
snapshot.Should().Contain("Chips: 100");
|
|
snapshot.Should().Contain("Round: 1");
|
|
}
|
|
|
|
[Fact]
|
|
public void Snapshot_AfterDeal()
|
|
{
|
|
var (world, group) = TestHelpers.SetupGame(seed: 42);
|
|
|
|
world.Commands.Enqueue(new PlaceBetCommand { Amount = 10 });
|
|
group.RunLogical();
|
|
|
|
var snapshot = TestHelpers.SnapshotWorld(world);
|
|
_output.WriteLine(snapshot);
|
|
|
|
snapshot.Should().Contain("Phase: PlayerTurn");
|
|
snapshot.Should().Contain("Chips: 90");
|
|
snapshot.Should().Contain("Bet: 10");
|
|
snapshot.Should().Contain("Player hand:");
|
|
snapshot.Should().Contain("Dealer hand:");
|
|
snapshot.Should().Contain("Cards in deck:");
|
|
}
|
|
|
|
[Fact]
|
|
public void Snapshot_AfterHit()
|
|
{
|
|
var (world, group) = TestHelpers.SetupGame(seed: 42);
|
|
|
|
world.Commands.Enqueue(new PlaceBetCommand { Amount = 10 });
|
|
group.RunLogical();
|
|
|
|
world.Commands.Enqueue(new HitCommand());
|
|
group.RunLogical();
|
|
|
|
var snapshot = TestHelpers.SnapshotWorld(world);
|
|
_output.WriteLine(snapshot);
|
|
|
|
snapshot.Should().NotContain("Phase: Dealing");
|
|
}
|
|
|
|
[Fact]
|
|
public void Snapshot_AfterStand()
|
|
{
|
|
var (world, group) = TestHelpers.SetupGame(seed: 42);
|
|
|
|
world.Commands.Enqueue(new PlaceBetCommand { Amount = 10 });
|
|
group.RunLogical();
|
|
|
|
world.Commands.Enqueue(new StandCommand());
|
|
group.RunLogical();
|
|
|
|
var snapshot = TestHelpers.SnapshotWorld(world);
|
|
_output.WriteLine(snapshot);
|
|
|
|
snapshot.Should().Contain("Phase: RoundOver");
|
|
snapshot.Should().Contain("Result:");
|
|
}
|
|
|
|
[Fact]
|
|
public void Log_ReactivityDuringRound()
|
|
{
|
|
var (world, group) = TestHelpers.SetupGame(seed: 42);
|
|
|
|
using var capture = new ObservableCapture(world);
|
|
capture.FormatWith<Card>(c => $"{c.Rank} of {c.Suit}");
|
|
capture.FormatWith<GameState>(s => $"{s.Phase} Chips={s.Chips} Bet={s.CurrentBet} Round={s.RoundNumber}");
|
|
|
|
world.Commands.Enqueue(new PlaceBetCommand { Amount = 10 });
|
|
group.RunLogical();
|
|
|
|
world.Commands.Enqueue(new StandCommand());
|
|
group.RunLogical();
|
|
|
|
var logText = string.Join("\n", capture.GetLogLines());
|
|
_output.WriteLine(logText);
|
|
|
|
capture.GetLogLines().Should().Contain(l => l.Contains("EntityAdded"));
|
|
capture.GetLogLines().Should().Contain(l => l.Contains("ComponentAdded") && l.Contains("Card"));
|
|
capture.GetLogLines().Should().Contain(l => l.Contains("ComponentModified") && l.Contains("GameState"));
|
|
}
|
|
|
|
[Fact]
|
|
public void Serialization_RoundTrip_PreservesCoreState()
|
|
{
|
|
var (world, group) = TestHelpers.SetupGame(seed: 42);
|
|
|
|
world.Commands.Enqueue(new PlaceBetCommand { Amount = 10 });
|
|
group.RunLogical();
|
|
|
|
var before = TestHelpers.SnapshotWorld(world);
|
|
|
|
using var stream = new MemoryStream();
|
|
WorldSerializer.Save(world, stream);
|
|
stream.Position = 0;
|
|
|
|
var world2 = new World();
|
|
WorldSerializer.Load(world2, stream);
|
|
|
|
var after = TestHelpers.SnapshotWorld(world2);
|
|
|
|
_output.WriteLine("=== Before ===");
|
|
_output.WriteLine(before);
|
|
_output.WriteLine("=== After ===");
|
|
_output.WriteLine(after);
|
|
|
|
var state = world2.ReadSingleton<GameState>();
|
|
state.Phase.Should().Be(GamePhase.PlayerTurn);
|
|
state.Chips.Should().Be(90);
|
|
state.CurrentBet.Should().Be(10);
|
|
state.RoundNumber.Should().Be(1);
|
|
|
|
after.Should().Contain("Card entities: 52");
|
|
}
|
|
} |