ActionService tests and Equality

This commit is contained in:
Martin Berg Alstad 2023-07-12 14:07:32 +02:00
parent 27d13caf5d
commit ea2f31b905
9 changed files with 147 additions and 83 deletions

View File

@ -1,6 +1,11 @@
using System.Text.Json;
using BackendTests.TestUtils;
using Microsoft.CSharp.RuntimeBinder;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using NSubstitute; using NSubstitute;
using pacMan.Game; using pacMan.Game;
using pacMan.Game.Interfaces;
using pacMan.Game.Items;
using pacMan.Interfaces; using pacMan.Interfaces;
using pacMan.Services; using pacMan.Services;
@ -9,13 +14,13 @@ namespace BackendTests.Services;
public class ActionServiceTests public class ActionServiceTests
{ {
private IActionService _service = null!; private IActionService _service = null!;
private IWebSocketService _wssMock = null!; private IWebSocketService _wssSub = null!;
[SetUp] [SetUp]
public void Setup() public void Setup()
{ {
_wssMock = Substitute.For<WebSocketService>(Substitute.For<ILogger<WebSocketService>>()); _wssSub = Substitute.For<WebSocketService>(Substitute.For<ILogger<WebSocketService>>());
_service = new ActionService(Substitute.For<ILogger<ActionService>>(), _wssMock); _service = new ActionService(Substitute.For<ILogger<ActionService>>(), _wssSub);
} }
#region RollDice() #region RollDice()
@ -47,13 +52,26 @@ public class ActionServiceTests
[Test] [Test]
public void PlayerInfo_DataIsNotPlayer() public void PlayerInfo_DataIsNotPlayer()
{ {
Assert.Fail(); var message = new ActionMessage
{
Action = GameAction.PlayerInfo,
Data = new Box { Colour = "white", Pellets = new List<Pellet>() }
};
Assert.Throws<RuntimeBinderException>(() => _service.PlayerInfo(message));
} }
[Test] [Test]
public void PlayerInfo_DataIsPlayer() public void PlayerInfo_DataIsPlayer()
{ {
Assert.Fail(); var player = Players.Create("white");
var message = new ActionMessage
{
Action = GameAction.PlayerInfo,
Data = JsonSerializer.Serialize(player)
};
var players = _service.PlayerInfo(message);
Assert.That(new List<IPlayer> { player }, Is.EqualTo(players));
} }
#endregion #endregion

View File

@ -1,7 +1,7 @@
using BackendTests.TestUtils;
using pacMan.Exceptions; using pacMan.Exceptions;
using pacMan.Game; using pacMan.Game;
using pacMan.Game.Interfaces; using pacMan.Game.Interfaces;
using pacMan.Game.Items;
using pacMan.Services; using pacMan.Services;
using pacMan.Utils; using pacMan.Utils;
@ -20,72 +20,13 @@ public class GameGroupTests
public void Setup() public void Setup()
{ {
_gameGroup = new GameGroup(); _gameGroup = new GameGroup();
const string redColour = "red"; _redPlayer = Players.Create("red");
_redPlayer = new Player _bluePlayer = Players.Create("blue");
{ _yellowPlayer = Players.Create("yellow");
Name = "Red", _greenPlayer = Players.Create("green");
Colour = redColour, _purplePlayer = Players.Create("purple");
PacMan = CreatePacMan(redColour),
Box = CreateBox(redColour)
};
const string blueColour = "blue";
_bluePlayer = new Player
{
Name = "Blue",
Colour = blueColour,
PacMan = CreatePacMan(blueColour),
Box = CreateBox(blueColour)
};
const string yellowColour = "yellow";
_yellowPlayer = new Player
{
Name = "Yellow",
Colour = yellowColour,
PacMan = CreatePacMan(yellowColour),
Box = CreateBox(yellowColour)
};
const string greenColour = "green";
_greenPlayer = new Player
{
Name = "Green",
Colour = greenColour,
PacMan = CreatePacMan(greenColour),
Box = CreateBox(greenColour)
};
const string purpleColour = "purple";
_purplePlayer = new Player
{
Name = "Purple",
Colour = purpleColour,
PacMan = CreatePacMan(purpleColour),
Box = CreateBox(purpleColour)
};
} }
private static Character CreatePacMan(string colour) =>
new()
{
Colour = colour,
IsEatable = true,
Type = CharacterType.PacMan
};
private static Box CreateBox(string colour) =>
new()
{
Colour = colour,
Pellets = new List<Pellet>()
};
private static IPlayer Clone(IPlayer player) =>
new Player
{
Box = player.Box,
Colour = player.Colour,
Name = player.Name,
PacMan = player.PacMan
};
private void AddFullParty() private void AddFullParty()
{ {
_gameGroup.AddPlayer(_bluePlayer); _gameGroup.AddPlayer(_bluePlayer);
@ -115,7 +56,7 @@ public class GameGroupTests
[Test] [Test]
public void AddPlayer_WhenNameExists() public void AddPlayer_WhenNameExists()
{ {
var redClone = Clone(_redPlayer); var redClone = Players.Clone(_redPlayer);
_gameGroup.AddPlayer(_redPlayer); _gameGroup.AddPlayer(_redPlayer);
var added = _gameGroup.AddPlayer(redClone); var added = _gameGroup.AddPlayer(redClone);
Assert.That(added, Is.True); Assert.That(added, Is.True);

View File

@ -0,0 +1,40 @@
using pacMan.Game;
using pacMan.Game.Interfaces;
using pacMan.Game.Items;
namespace BackendTests.TestUtils;
public class Players
{
internal static IPlayer Create(string colour) =>
new Player
{
Name = colour,
Colour = colour,
PacMan = CreatePacMan(colour),
Box = CreateBox(colour)
};
internal static Character CreatePacMan(string colour) =>
new()
{
Colour = colour,
Type = CharacterType.PacMan
};
internal static Box CreateBox(string colour) =>
new()
{
Colour = colour,
Pellets = new List<Pellet>()
};
internal static IPlayer Clone(IPlayer player) =>
new Player
{
Box = player.Box,
Colour = player.Colour,
Name = player.Name,
PacMan = player.PacMan
};
}

View File

@ -1,12 +1,29 @@
namespace pacMan.Game; namespace pacMan.Game;
public class Character public class Character : IEquatable<Character>
{ {
public required string Colour { get; set; } public required string Colour { get; set; }
public MovePath? Position { get; set; } public MovePath? Position { get; set; }
public required bool IsEatable { get; set; } public bool IsEatable { get; set; } = true;
public DirectionalPosition? SpawnPosition { get; set; } public DirectionalPosition? SpawnPosition { get; set; }
public required CharacterType Type { get; set; } public required CharacterType Type { get; set; }
public bool Equals(Character? other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return Colour == other.Colour && Equals(Position, other.Position) && IsEatable == other.IsEatable &&
Equals(SpawnPosition, other.SpawnPosition) && Type == other.Type;
}
public override bool Equals(object? obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
return obj.GetType() == GetType() && Equals((Character)obj);
}
public override int GetHashCode() => HashCode.Combine(Colour, Position, IsEatable, SpawnPosition, (int)Type);
} }
public enum CharacterType public enum CharacterType
@ -14,4 +31,4 @@ public enum CharacterType
PacMan, PacMan,
Ghost, Ghost,
Dummy Dummy
} }

View File

@ -2,18 +2,23 @@ using pacMan.Game.Interfaces;
namespace pacMan.Game.Items; namespace pacMan.Game.Items;
public class Box public class Box : IEquatable<Box>
{ {
public required List<Pellet>? Pellets { get; init; } = new(); public required List<Pellet>? Pellets { get; init; } = new();
public required string Colour { get; init; } public required string Colour { get; init; }
public int CountNormal => Pellets?.Count(pellet => !pellet.IsPowerPellet) ?? 0; public int CountNormal => Pellets?.Count(pellet => !pellet.IsPowerPellet) ?? 0;
public IEnumerator<IPellet> GetEnumerator() public bool Equals(Box? other)
{ {
return Pellets?.GetEnumerator() ?? new List<Pellet>.Enumerator(); if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return (Equals(Pellets, other.Pellets) || (Pellets?.Count == 0 && other.Pellets?.Count == 0)) &&
Colour == other.Colour;
} }
public IEnumerator<IPellet> GetEnumerator() => Pellets?.GetEnumerator() ?? new List<Pellet>.Enumerator();
// IEnumerator IEnumerable.GetEnumerator() // IEnumerator IEnumerable.GetEnumerator()
// { // {
// return GetEnumerator(); // return GetEnumerator();
@ -23,4 +28,13 @@ public class Box
{ {
Pellets?.Add(pellet); Pellets?.Add(pellet);
} }
}
public override bool Equals(object? obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
return obj.GetType() == GetType() && Equals((Box)obj);
}
public override int GetHashCode() => HashCode.Combine(Pellets, Colour);
}

View File

@ -2,7 +2,23 @@ using pacMan.Game.Interfaces;
namespace pacMan.Game.Items; namespace pacMan.Game.Items;
public class Pellet : IPellet public class Pellet : IPellet, IEquatable<Pellet>
{ {
public bool Equals(Pellet? other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return IsPowerPellet == other.IsPowerPellet;
}
public bool IsPowerPellet { get; init; } public bool IsPowerPellet { get; init; }
}
public override bool Equals(object? obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
return obj.GetType() == GetType() && Equals((Pellet)obj);
}
public override int GetHashCode() => IsPowerPellet.GetHashCode();
}

View File

@ -2,11 +2,28 @@ using pacMan.Game.Interfaces;
namespace pacMan.Game.Items; namespace pacMan.Game.Items;
public class Player : IPlayer public class Player : IPlayer, IEquatable<Player>
{ {
public bool Equals(Player? other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return Name == other.Name && PacMan.Equals(other.PacMan) && Colour == other.Colour && Box.Equals(other.Box) &&
State == other.State;
}
public required string Name { get; init; } public required string Name { get; init; }
public required Character PacMan { get; init; } public required Character PacMan { get; init; }
public required string Colour { get; init; } public required string Colour { get; init; }
public required Box Box { get; init; } public required Box Box { get; init; }
public State State { get; set; } = State.WaitingForPlayers; public State State { get; set; } = State.WaitingForPlayers;
}
public override bool Equals(object? obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
return obj.GetType() == GetType() && Equals((Player)obj);
}
public override int GetHashCode() => HashCode.Combine(Name, PacMan, Colour, Box, (int)State);
}

View File

@ -54,6 +54,7 @@ public class ActionService : IActionService // TODO tests
{ {
try try
{ {
// Receieved JsonElement from frontend
_player = JsonSerializer.Deserialize<Player>(message.Data); _player = JsonSerializer.Deserialize<Player>(message.Data);
_group = _wsService.AddPlayer(_player); _group = _wsService.AddPlayer(_player);
} }

View File

@ -4,7 +4,7 @@ using pacMan.Game.Interfaces;
namespace pacMan.Services; namespace pacMan.Services;
public class GameGroup // TODO tests public class GameGroup
{ {
private readonly Random _random = new(); private readonly Random _random = new();
public List<IPlayer> Players { get; } = new(); public List<IPlayer> Players { get; } = new();