using GameHandler.DeathGame; using GameModel; using GameModel.DeathGame; using NuGet.Frameworks; using NUnit.Framework; using System; using System.Collections.Generic; using System.Linq; using System.Runtime; using System.Text; using System.Threading.Tasks; namespace GameHandler.UnitTests.DeathGame { [TestFixture] public class DeathGameHandlerTests { private DeathGameSettings _settings; private DeathGameHandler _gh; private int[] _players; [SetUp] public void SetUp() { _settings = new DeathGameSettings(6); _gh = new DeathGameHandler(); _players = new[] { 1, 2, 3, 4, 5, 6 }; } [Test] public void CreateGameModelWithDuplicatePlayers_ThrowsException() { var players = new[] { 1, 2, 3, 1 }; Assert.That(() => _gh.InitGameModel(players,_settings), Throws.TypeOf()); } [Test] public void CreateGameModelWithTooManyPlayers_ThrowsException() { var players = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 }; Assert.That(() => _gh.InitGameModel(players, _settings), Throws.TypeOf()); } [Test] public void CreateGameModelWithTooLessPlayers_ThrowsException() { var players = new[] { 1, 2 }; Assert.That(() => _gh.InitGameModel(players, _settings), Throws.TypeOf()); } [Test] [TestCase(2)] [TestCase(13)] public void InvalidMaxCoffinSize_ThrowsException(int maxCoffinSize) { var players = new[] { 1, 2, 3, 4 }; var invalidSettings = new DeathGameSettings(maxCoffinSize); Assert.That(() => _gh.InitGameModel(players, invalidSettings), Throws.TypeOf()); } [Test] public void NewGameModel_IsWithoutXandLineCount() { var gm = _gh.InitGameModel(_players, _settings); Assert.That(gm.Coffins.Count, Is.EqualTo(_players.Count())); Assert.That(gm.Coffins.Any(_ => _.XCount > 0), Is.False); Assert.That(gm.Coffins.Any(_ => _.LineCount > 0), Is.False); } [Test] public void InvalidFirstThrow_RaisesExpense() { var gm = _gh.InitGameModel(_players, _settings); int failedCoffinPlayerId = 0; ExpenseTrigger[] failed = Array.Empty(); _gh.GameExpenseOccured += (sender, arg) => { failed = ((GameExenseEventArgs)arg).Triggers; failedCoffinPlayerId = ((GameExenseEventArgs)arg).PlayerId; }; var newGm = _gh.CalcNextModel(gm, 2, true, false); Assert.That(failedCoffinPlayerId, Is.EqualTo(newGm.Coffins.Last().PlayerId)); } [Test] public void ValidFirstThrow_DoesNotRaisesExpense() { var gm = _gh.InitGameModel(_players, _settings); int failedCoffinPlayerId = 0; ExpenseTrigger[] failed = Array.Empty(); _gh.GameExpenseOccured += (sender, arg) => { failed = ((GameExenseEventArgs)arg).Triggers; failedCoffinPlayerId = ((GameExenseEventArgs)arg).PlayerId; }; var newGm = _gh.CalcNextModel(gm, 3, true, false); Assert.That(failed, Is.Empty); Assert.That(failedCoffinPlayerId, Is.Zero); } [Test] public void AfterFirstThrow_SomeFirstPlayerHasAnX() { var gm = _gh.InitGameModel(_players, _settings); var newGm = _gh.CalcNextModel(gm, 2, true, false); Assert.That(newGm.Coffins.Last().XCount, Is.EqualTo(1)); } [Test] public void AfterThrowIntoAllPins_SomeFirstPlayerHasAnX() { var gm = _gh.InitGameModel(_players, _settings); var newGm = _gh.CalcNextModel(gm, 2, true, true); Assert.That(newGm.Coffins.Last().XCount, Is.EqualTo(1)); } [Test] public void AfterThrowWithoutPins_SomeFirstPlayerHasAnLine() { var gm = _gh.InitGameModel(_players, _settings); var newGm = _gh.CalcNextModel(gm, 0, false, false); Assert.That(newGm.Coffins.Last().LineCount, Is.EqualTo(1)); Assert.That(newGm.Coffins.Last().XCount, Is.EqualTo(0)); } [Test] public void ThirdX_ChangesToAddedLineAndZeroX() { var gm = _gh.InitGameModel(_players, _settings); var coffins = gm.Coffins.ToList(); var first = gm.Coffins.First() with { XCount = 2 }; coffins.RemoveAt(0); coffins.Insert(0, first); var gm2 = gm with { Coffins = coffins.ToArray(), Id = 2 }; var newGm = _gh.CalcNextModel(gm2, 2, true, true); Assert.That(newGm.Coffins.Last().XCount, Is.EqualTo(0)); Assert.That(newGm.Coffins.Last().LineCount, Is.EqualTo(first.LineCount + 2)); // one for third x, one for failed throw } [Test] public void FirstPlayerIsLast_AfterModelUpdate() { var gm = _gh.InitGameModel(_players, _settings); var first = gm.Coffins.First(); DeathGameModel? newGm = null; Assert.That(() => { newGm = _gh.CalcNextModel(gm, 2, false, false); }, Throws.Nothing); Assert.That(first.PlayerId,Is.EqualTo(newGm.Coffins.Last().PlayerId)); Assert.That(gm.Coffins.Count, Is.EqualTo(newGm.Coffins.Count())); } [Test] public void AllPins_CausesLineAtPreviousPlayer() { var gm = _gh.InitGameModel(_players, _settings); var prev = gm.Coffins.Last(); var newGm = _gh.CalcNextModel(gm, 2, false, true); var prevNew = newGm.Coffins.First(_ => _.PlayerId == prev.PlayerId); Assert.That(prevNew.LineCount, Is.EqualTo(prev.LineCount + 1)); } [Test] public void LineLimit_CausesDeath() { var gm = _gh.InitGameModel(_players, _settings); Coffin? deadCoffin = null; _gh.CoffinCompleted += (c) => deadCoffin = c; var coffins = gm.Coffins.ToList(); var first = gm.Coffins.First() with { LineCount = _settings.MaxCoffinSize }; coffins.RemoveAt(0); coffins.Insert(0, first); var gm2 = gm with { Coffins = coffins.ToArray(), Id = 2 }; var newGm = _gh.CalcNextModel(gm2, 0, false, false); Assert.That(deadCoffin.PlayerId, Is.EqualTo(first.PlayerId)); Assert.That(newGm.Coffins.FirstOrDefault(_ => _.PlayerId == deadCoffin.PlayerId), Is.Null); } [Test] public void PreviousPlayerIsDead_WhenCurrentClearsBoard() { var gm = _gh.InitGameModel(_players, _settings); Coffin? deadCoffin = null; _gh.CoffinCompleted += (c) => deadCoffin = c; var coffins = gm.Coffins.ToList(); var last = gm.Coffins.Last() with { LineCount = _settings.MaxCoffinSize }; coffins.RemoveAt(gm.Coffins.Length-1); coffins.Insert(gm.Coffins.Length - 1, last); var gm2 = gm with { Coffins = coffins.ToArray(), Id = 2 }; var newGm = _gh.CalcNextModel(gm2, 2, false, true); Assert.That(deadCoffin.PlayerId, Is.EqualTo(last.PlayerId)); Assert.That(newGm.Coffins.FirstOrDefault(_ => _.PlayerId == deadCoffin.PlayerId), Is.Null); } [Test] public void NextPlayerIsDead_WhenCurrentCausesThirdX() { var gm = _gh.InitGameModel(_players, _settings); Coffin? deadCoffin = null; _gh.CoffinCompleted += (c) => deadCoffin = c; var coffins = gm.Coffins.ToList(); var next = coffins[1] with { XCount = 2, LineCount = _settings.MaxCoffinSize }; coffins.RemoveAt(1); coffins.Insert(1, next); var gm2 = gm with { Coffins = coffins.ToArray(), Id = 2 }; var newGm = _gh.CalcNextModel(gm2, 2, false, true); Assert.That(deadCoffin.PlayerId, Is.EqualTo(next.PlayerId)); Assert.That(newGm.Coffins.FirstOrDefault(_ => _.PlayerId == deadCoffin.PlayerId), Is.Null); } [Test] public void OnePlayer_CanKillPreviousAndNext() { var gm = _gh.InitGameModel(_players, _settings); var bodies = new List(); _gh.CoffinCompleted += (c) => bodies.Add(c); var coffins = gm.Coffins.ToList(); var next = coffins[1] with { XCount = 2, LineCount = _settings.MaxCoffinSize }; coffins.RemoveAt(1); coffins.Insert(1, next); var last = coffins.Last() with { XCount = 2, LineCount = _settings.MaxCoffinSize }; coffins.RemoveAt(coffins.Count()-1); coffins.Insert(coffins.Count(), last); var gm2 = gm with { Coffins = coffins.ToArray(), Id = 2 }; var newGm = _gh.CalcNextModel(gm2, 2, false, true); Assert.That(bodies.Count, Is.EqualTo(2)); foreach (var body in bodies) { Assert.That(newGm.Coffins.FirstOrDefault(_ => _.PlayerId == body.PlayerId), Is.Null); } } } }