using FakeItEasy; using MiniJeuxFinal.Games; using MiniJeuxFinal.Ui; using MiniJeuxFinal.Wrappers; using NFluent; namespace MiniJeuxFinal.Test.Ui { public class GameRunnerConsoleTests { private readonly IGame _fakeGame; private readonly IConsole _fakeConsole; private readonly GameRunnerConsole _target; public GameRunnerConsoleTests() { _fakeGame = A.Fake(); _fakeConsole = A.Fake(); _target = new GameRunnerConsole(_fakeConsole, _fakeGame); } // Dispose pour nettoyer les tests public void Dispose() => _target.Dispose(); [Fact] public void Constructor_Should_Subscribe_To_Game_Events() { A.CallTo(_fakeGame) .Where(call => call.Method.Name == "add_TurnStarted") .MustHaveHappenedOnceExactly(); A.CallTo(_fakeGame) .Where(call => call.Method.Name == "add_TurnEnded") .MustHaveHappenedOnceExactly(); A.CallTo(_fakeGame) .Where(call => call.Method.Name == "add_GameEnded") .MustHaveHappenedOnceExactly(); } [Fact] public void Dispose_Should_Unsubscribe_From_Game_Events() { _target.Dispose(); A.CallTo(_fakeGame) .Where(call => call.Method.Name == "remove_TurnStarted") .MustHaveHappenedOnceExactly(); A.CallTo(_fakeGame) .Where(call => call.Method.Name == "remove_TurnEnded") .MustHaveHappenedOnceExactly(); A.CallTo(_fakeGame) .Where(call => call.Method.Name == "remove_GameEnded") .MustHaveHappenedOnceExactly(); } [Fact] public void Run_Should_Display_GameName_Then_Start_Game() { const string gameName = "PIERRE-PAPIER-CISEAUX"; A.CallTo(() => _fakeGame.Name).Returns(gameName); _target.Run(); A.CallTo(() => _fakeConsole.WriteLine(gameName)).MustHaveHappenedOnceExactly(); A.CallTo(() => _fakeConsole.WriteLine()).MustHaveHappenedOnceExactly(); A.CallTo(() => _fakeGame.Start()).MustHaveHappenedOnceExactly(); var calls = Fake.GetCalls(_fakeConsole).ToList(); Check.That(calls[0].Arguments[0]).IsEqualTo(gameName); Check.That(calls[1].Arguments).IsEmpty(); // WriteLine() sans paramètre } [Fact] public void OnTurnStarted_Should_Display_Both_Choices() { _fakeGame.TurnStarted += Raise.FreeForm.With(null, ("1", "2")); A.CallTo(() => _fakeConsole.WriteLine($"Tu joues : 1")) .MustHaveHappenedOnceExactly(); A.CallTo(() => _fakeConsole.WriteLine($"L'ordinateur joue : 2")) .MustHaveHappenedOnceExactly(); } [Theory] [InlineData(null, "Égalité !")] // winner = null [InlineData("Joueur1", "Joueur1 gagne la manche")] // winner = Joueur1 public void OnTurnEnded_Should_Clear_And_Display_Results(string? winnerName, string expectedMessage) { // Arrange IPlayer? fakeWinner = winnerName != null ? A.Fake() : null; if (fakeWinner != null) A.CallTo(() => fakeWinner.Name).Returns(winnerName); var fakePlayer1 = A.Fake(); var fakePlayer2 = A.Fake(); A.CallTo(() => fakePlayer1.ToString()).Returns("Joueur1 (3 pts)"); A.CallTo(() => fakePlayer2.ToString()).Returns("Ordinateur (1 pt)"); var players = new[] { fakePlayer1, fakePlayer2 }; var eventArgs = (fakeWinner, players); // Capturer le handler EventHandler<(IPlayer?, IPlayer[])>? handler = null; A.CallTo(_fakeGame) .Where(call => call.Method.Name == "add_TurnEnded") .Invokes(call => handler = (EventHandler<(IPlayer?, IPlayer[])>)call.Arguments[0]); var target2 = new GameRunnerConsole(_fakeConsole, _fakeGame); handler?.Invoke(this, eventArgs); A.CallTo(() => _fakeConsole.Clear()) .MustHaveHappenedOnceExactly() .Then(A.CallTo(() => _fakeConsole.WriteLine(expectedMessage)) .MustHaveHappenedOnceExactly()) .Then(A.CallTo(() => _fakeConsole.WriteLine(A.That.Contains("Score :"))) .MustHaveHappenedOnceExactly()); target2.Dispose(); } [Fact] public void OnGameEnded_Should_Display_Winner_And_Final_Score() { var fakeWinner = A.Fake(); var fakeLoser = A.Fake(); A.CallTo(() => fakeWinner.Name).Returns("Joueur1"); A.CallTo(() => fakeWinner.Score).Returns(5); A.CallTo(() => fakeLoser.Name).Returns("Ordinateur"); A.CallTo(() => fakeLoser.Score).Returns(2); var players = new[] { fakeWinner, fakeLoser }; var eventArgs = (fakeWinner, players); EventHandler<(IPlayer, IPlayer[])>? handler = null; A.CallTo(_fakeGame) .Where(call => call.Method.Name == "add_GameEnded") .Invokes(call => handler = (EventHandler<(IPlayer, IPlayer[])>)call.Arguments[0]); var target2 = new GameRunnerConsole(_fakeConsole, _fakeGame); handler?.Invoke(this, eventArgs); A.CallTo(() => _fakeConsole.WriteLine("Joueur1 A GAGNÉ ! 🎉🎉🎉")) .MustHaveHappenedOnceExactly(); A.CallTo(() => _fakeConsole.WriteLine("Score final : 5 - 2")) .MustHaveHappenedOnceExactly(); target2.Dispose(); } } }