using FluentAssertions; using Game.CardWars; using OECS; using Xunit; namespace Game.CardWars.Tests; public class GameSetupTests { private static (World World, SystemGroup Group) Setup() { // Reset registry state between tests. CardEffectRegistry.ClearForTests(); return GameFactory.Create(playerCount: 2, seed: 42); } [Fact] public void CreateGame_CreatesPlayersAndDecks() { var (world, _) = Setup(); var state = world.ReadSingleton(); state.Phase.Should().Be(GamePhase.PlayPhase); state.PlayerCount.Should().Be(2); state.RoundNumber.Should().Be(1); GameUtil.FindEntity(world).Should().NotBe(Entity.Null); GameUtil.FindAllEntities(world).Should().HaveCount(2); GameUtil.FindAllEntities(world).Should().HaveCount(2); GameUtil.FindAllEntities(world).Should().HaveCount(2); GameUtil.FindAllEntities(world).Should().NotBeEmpty(); } [Fact] public void StartingHand_HasThreeCards() { var (world, _) = Setup(); foreach (var player in GameUtil.FindAllEntities(world)) { var hand = GameUtil.GetHandCards(world, player); hand.Should().HaveCount(3); } } [Fact] public void PlayCard_MovesCardFromHandToField() { var (world, group) = Setup(); var state = world.ReadSingleton(); var player = PlayCardCommand.FindPlayerByIndex(world, state.CurrentPlayerIndex); var hand = GameUtil.GetHandCards(world, player); var cardInHand = hand[0]; var def = world.ReadComponent(cardInHand); world.Commands.Enqueue(new PlayCardCommand { CardEntity = cardInHand, Rank = def.Ranks[0], FaceDown = false, TargetPlayer = null }); group.RunLogical(); GameUtil.GetFieldCards(world, player).Should().Contain(cardInHand); var cardData = world.ReadComponent(cardInHand); cardData.Rank.Should().Be(def.Ranks[0]); cardData.FaceDown.Should().BeFalse(); } [Fact] public void PlayCardFaceDown_CardIsHidden() { var (world, group) = Setup(); var state = world.ReadSingleton(); var player = PlayCardCommand.FindPlayerByIndex(world, state.CurrentPlayerIndex); var hand = GameUtil.GetHandCards(world, player); var cardInHand = hand[0]; var def = world.ReadComponent(cardInHand); world.Commands.Enqueue(new PlayCardCommand { CardEntity = cardInHand, Rank = def.Ranks[0], FaceDown = true, TargetPlayer = null }); group.RunLogical(); world.ReadComponent(cardInHand).FaceDown.Should().BeTrue(); } [Fact] public void FlipCard_RevealsFaceDownCard() { var (world, group) = Setup(); var state = world.ReadSingleton(); var player = PlayCardCommand.FindPlayerByIndex(world, state.CurrentPlayerIndex); var hand = GameUtil.GetHandCards(world, player); var cardInHand = hand[0]; var def = world.ReadComponent(cardInHand); // Play face-down. world.Commands.Enqueue(new PlayCardCommand { CardEntity = cardInHand, Rank = def.Ranks[0], FaceDown = true, TargetPlayer = null }); group.RunLogical(); // Advance to flip phase: both players skip. world.Commands.Enqueue(new SkipPlayCommand()); group.RunLogical(); world.Commands.Enqueue(new SkipPlayCommand()); group.RunLogical(); world.ReadSingleton().Phase.Should().Be(GamePhase.FlipPhase); // Flip it. world.Commands.Enqueue(new FlipCardCommand { CardEntity = cardInHand }); group.RunLogical(); world.ReadComponent(cardInHand).FaceDown.Should().BeFalse(); } [Fact] public void SkipPlay_AdvancesTurn() { var (world, group) = Setup(); var state = world.ReadSingleton(); int originalPlayer = state.CurrentPlayerIndex; world.Commands.Enqueue(new SkipPlayCommand()); group.RunLogical(); state = world.ReadSingleton(); state.CurrentPlayerIndex.Should().Be((originalPlayer + 1) % 2); } }