Merge pull request 'use-async-in-playerdb' (#186) from use-async-in-playerdb into main
continuous-integration/drone/push Build is passing Details

Reviewed-on: #186
pull/188/head^2
Alexis Drai 2 years ago
commit 84f52c3dce

@ -10,19 +10,20 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Threading.Tasks;
namespace App
{
internal static class Program
{
static void Main(string[] args)
static async Task Main(string[] args)
{
// MODEL stuff
ILoader loader = new Stub();
MasterOfCeremonies masterOfCeremonies;
try
{
masterOfCeremonies = loader.LoadApp();
masterOfCeremonies = await loader.LoadApp();
}
catch (Exception ex)
{
@ -48,7 +49,7 @@ namespace App
try
{
// persist them as models !
masterOfCeremonies.GlobalPlayerManager.Add(entity.ToModel());
await masterOfCeremonies.GlobalPlayerManager.Add(entity.ToModel());
Debug.WriteLine($"{entity.ID} -- {entity.Name}");
}
catch (Exception ex) { Debug.WriteLine($"{ex.Message}\n... Never mind"); }
@ -81,38 +82,38 @@ namespace App
break;
case "l":
string loadName = ChooseGame(masterOfCeremonies);
string loadName = await ChooseGame(masterOfCeremonies);
if (masterOfCeremonies.GameManager.GetOneByName(loadName) != null)
{
Play(masterOfCeremonies, loadName);
await Play(masterOfCeremonies, loadName);
}
break;
case "n":
if (!masterOfCeremonies.DiceGroupManager.GetAll().Any())
if (!(await masterOfCeremonies.DiceGroupManager.GetAll()).Any())
{
Console.WriteLine("make at least one dice group first, then try again");
break;
}
Console.WriteLine("add dice to the game");
IEnumerable<Die> newGameDice = PrepareDice(masterOfCeremonies);
IEnumerable<Die> newGameDice = await PrepareDice(masterOfCeremonies);
string newGameName;
Console.WriteLine("give this new game a name\n>");
newGameName = Console.ReadLine();
Console.WriteLine("add players to the game");
PlayerManager playerManager = PreparePlayers(masterOfCeremonies);
PlayerManager playerManager = await PreparePlayers(masterOfCeremonies);
masterOfCeremonies.StartNewGame(newGameName, playerManager, newGameDice);
Play(masterOfCeremonies, newGameName);
await masterOfCeremonies.StartNewGame(newGameName, playerManager, newGameDice);
await Play(masterOfCeremonies, newGameName);
break;
case "d":
string deleteName = ChooseGame(masterOfCeremonies);
masterOfCeremonies.GameManager.Remove(masterOfCeremonies.GameManager.GetOneByName(deleteName));
string deleteName = await ChooseGame(masterOfCeremonies);
masterOfCeremonies.GameManager.Remove(await masterOfCeremonies.GameManager.GetOneByName(deleteName));
break;
case "c":
@ -151,19 +152,19 @@ namespace App
newGroupDice.Add(die);
}
}
masterOfCeremonies.DiceGroupManager.Add(new KeyValuePair<string, IEnumerable<Die>>(newGroupName, newGroupDice));
await masterOfCeremonies.DiceGroupManager.Add(new KeyValuePair<string, IEnumerable<Die>>(newGroupName, newGroupDice));
break;
case "p":
ShowPlayers(masterOfCeremonies);
await ShowPlayers(masterOfCeremonies);
break;
case "i":
ShowDice(masterOfCeremonies);
await ShowDice(masterOfCeremonies);
break;
case "y":
PreparePlayers(masterOfCeremonies);
await PreparePlayers(masterOfCeremonies);
break;
default:
@ -178,7 +179,7 @@ namespace App
using (DiceAppDbContext db = new())
{
// get all the players from the app's memory
IEnumerable<Player> models = masterOfCeremonies.GlobalPlayerManager.GetAll();
IEnumerable<Player> models = await masterOfCeremonies.GlobalPlayerManager.GetAll();
// create a PlayerDbManager (and inject it with the DB)
PlayerDbManager playerDbManager = new(db);
@ -190,7 +191,7 @@ namespace App
try // to persist them
{ // as entities !
PlayerEntity entity = model.ToEntity();
playerDbManager.Add(entity);
await playerDbManager.Add(entity);
Debug.WriteLine($"{entity.ID} -- {entity.Name}");
}
// what if there's already a player with that name? Exception (see PlayerEntity's annotations)
@ -201,12 +202,12 @@ namespace App
catch (Exception ex) { Debug.WriteLine($"{ex.Message}\n... Couldn't use the database"); }
}
private static void Play(MasterOfCeremonies masterOfCeremonies, string name)
private static async Task Play(MasterOfCeremonies masterOfCeremonies, string name)
{
string menuChoicePlay = "";
while (menuChoicePlay != "q")
{
Game game = masterOfCeremonies.GameManager.GetOneByName(name);
Game game = await masterOfCeremonies.GameManager.GetOneByName(name);
Console.WriteLine($"{game.GetWhoPlaysNow()}'s turn\n" +
"q... quit\n" +
"h... show history\n" +
@ -224,21 +225,21 @@ namespace App
}
break;
case "s":
masterOfCeremonies.GameManager.Add(game);
await masterOfCeremonies.GameManager.Add(game);
break;
default:
MasterOfCeremonies.PlayGame(game);
await MasterOfCeremonies.PlayGame(game);
Console.WriteLine(game.GetHistory().Last());
break;
}
}
}
private static string ChooseGame(MasterOfCeremonies masterOfCeremonies)
private static async Task<string> ChooseGame(MasterOfCeremonies masterOfCeremonies)
{
string name;
Console.WriteLine("which of these games?\n(choose by name)\n>");
foreach (Game game in masterOfCeremonies.GameManager.GetAll())
foreach (Game game in await masterOfCeremonies.GameManager.GetAll())
{
Console.WriteLine(game);
}
@ -246,18 +247,18 @@ namespace App
return name;
}
private static void ShowPlayers(MasterOfCeremonies masterOfCeremonies)
private static async Task ShowPlayers(MasterOfCeremonies masterOfCeremonies)
{
Console.WriteLine("Look at all them players!");
foreach (Player player in masterOfCeremonies.GlobalPlayerManager.GetAll())
foreach (Player player in await masterOfCeremonies.GlobalPlayerManager.GetAll())
{
Console.WriteLine(player);
}
}
private static void ShowDice(MasterOfCeremonies masterOfCeremonies)
private static async Task ShowDice(MasterOfCeremonies masterOfCeremonies)
{
foreach ((string name, IEnumerable<Die> dice) in masterOfCeremonies.DiceGroupManager.GetAll())
foreach ((string name, IEnumerable<Die> dice) in await masterOfCeremonies.DiceGroupManager.GetAll())
{
Console.WriteLine($"{name} -- {dice}");
}
@ -357,11 +358,11 @@ namespace App
}
}
private static IEnumerable<Die> PrepareDice(MasterOfCeremonies masterOfCeremonies)
private async static Task<IEnumerable<Die>> PrepareDice(MasterOfCeremonies masterOfCeremonies)
{
List<Die> result = new();
Console.WriteLine("all known dice or groups of dice:");
ShowDice(masterOfCeremonies);
await ShowDice(masterOfCeremonies);
string menuChoiceDice = "";
while (!(menuChoiceDice.Equals("ok") && result.Any()))
{
@ -369,7 +370,7 @@ namespace App
menuChoiceDice = Console.ReadLine();
if (!menuChoiceDice.Equals("ok"))
{
IEnumerable<Die> chosenDice = masterOfCeremonies.DiceGroupManager.GetOneByName(menuChoiceDice).Value;
IEnumerable<Die> chosenDice = (await masterOfCeremonies.DiceGroupManager.GetOneByName(menuChoiceDice)).Value;
foreach (Die die in chosenDice)
{
result.Add(die);
@ -378,28 +379,28 @@ namespace App
}
return result.AsEnumerable();
}
private static PlayerManager PreparePlayers(MasterOfCeremonies masterOfCeremonies)
private async static Task<PlayerManager> PreparePlayers(MasterOfCeremonies masterOfCeremonies)
{
PlayerManager result = new();
Console.WriteLine("all known players:");
ShowPlayers(masterOfCeremonies);
await ShowPlayers(masterOfCeremonies);
string menuChoicePlayers = "";
while (!(menuChoicePlayers.Equals("ok") && result.GetAll().Any()))
while (!(menuChoicePlayers.Equals("ok") && (await result.GetAll()).Any()))
{
Console.WriteLine("write the name of a player you want to add (at least one), or 'ok' if you're finished");
menuChoicePlayers = Console.ReadLine();
if (!menuChoicePlayers.Equals("ok"))
{
Player player = new(menuChoicePlayers);
if (!masterOfCeremonies.GlobalPlayerManager.GetAll().Contains(player))
if (!(await masterOfCeremonies.GlobalPlayerManager.GetAll()).Contains(player))
{
// if the player didn't exist, now it does... this is temporary
masterOfCeremonies.GlobalPlayerManager.Add(player);
await masterOfCeremonies.GlobalPlayerManager.Add(player);
}
// almost no checks, this is temporary
try
{
result.Add(player);
await result.Add(player);
}
catch (ArgumentException ex) { Debug.WriteLine($"{ex.Message}\n... Never mind"); }

@ -6,7 +6,8 @@ namespace Data.EF
{
public class DiceAppDbContext : DbContext, ILoader
{
public virtual MasterOfCeremonies LoadApp() { throw new NotImplementedException(); }
// will be async!
public virtual Task<MasterOfCeremonies> LoadApp() { throw new NotImplementedException(); }
public DbSet<PlayerEntity> Players { get; set; }

@ -1,13 +1,15 @@
using Data.EF.Players;
using Microsoft.EntityFrameworkCore;
using Model.Games;
using System.Linq.Expressions;
using System.Security.Cryptography.X509Certificates;
namespace Data.EF
{
public class DiceAppDbContextWithStub : DiceAppDbContext
{
public override MasterOfCeremonies LoadApp() { throw new NotImplementedException(); }
// will be async
public override Task<MasterOfCeremonies> LoadApp() { throw new NotImplementedException(); }
public DiceAppDbContextWithStub() { }
@ -20,7 +22,7 @@ namespace Data.EF
modelBuilder.Entity<PlayerEntity>().HasData(
new PlayerEntity { ID = Guid.NewGuid(), Name = "Alice" }, // some tests depend on this name
new PlayerEntity { ID = Guid.NewGuid(), Name = "Bob" }, // some tests depend on this name
new PlayerEntity { ID = new("6e856818-92f1-4d7d-b35c-f9c6687ef8e1"), Name = "Bob" }, // some tests depend on this name and this ID
new PlayerEntity { ID = Guid.NewGuid(), Name = "Clyde" }, // some tests depend on this name
new PlayerEntity { ID = Guid.NewGuid(), Name = "Dahlia" } // some tests depend on this name
);

@ -1,8 +1,6 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Model;
using Model.Players;
using System.Runtime.Intrinsics.Arm;
namespace Data.EF.Players
{
@ -45,7 +43,7 @@ namespace Data.EF.Players
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
public PlayerEntity Add(PlayerEntity toAdd)
public Task<PlayerEntity> Add(PlayerEntity toAdd)
{
CleanPlayerEntity(toAdd);
@ -54,14 +52,21 @@ namespace Data.EF.Players
throw new ArgumentException("this username is already taken", nameof(toAdd));
}
EntityEntry ee = db.Players.Add(toAdd);
db.SaveChanges();
return InternalAdd(toAdd);
}
private async Task<PlayerEntity> InternalAdd(PlayerEntity toAdd)
{
EntityEntry ee = await db.Players.AddAsync(toAdd);
await db.SaveChangesAsync();
return (PlayerEntity)ee.Entity;
}
public IEnumerable<PlayerEntity> GetAll()
public async Task<IEnumerable<PlayerEntity>> GetAll()
{
return db.Players.AsEnumerable();
List<PlayerEntity> players = new();
await Task.Run(() => players.AddRange(db.Players));
return players.AsEnumerable();
}
/// <summary>
@ -72,25 +77,30 @@ namespace Data.EF.Players
/// <exception cref="ArgumentException"></exception>
/// <exception cref="InvalidOperationException"></exception>
/// <returns></returns>
public PlayerEntity GetOneByName(string name)
public Task<PlayerEntity> GetOneByName(string name)
{
if (string.IsNullOrWhiteSpace(name))
{
throw new ArgumentException("Name property should not be null or whitespace", nameof(name));
}
name = name.Trim();
return db.Players.Where(p => p.Name == name).First();
return InternalGetOneByName(name);
}
public bool IsPresentByName(string name)
private async Task<PlayerEntity> InternalGetOneByName(string name)
{
return await db.Players.Where(p => p.Name == name).FirstAsync();
}
public async Task<bool> IsPresentByName(string name)
{
if (string.IsNullOrWhiteSpace(name))
{
return false;
}
name = name.Trim();
return db.Players.Where(p => p.Name == name).Any();
return await db.Players.Where(p => p.Name == name).FirstOrDefaultAsync() is not null;
}
/// <summary>
@ -102,8 +112,8 @@ namespace Data.EF.Players
public void Remove(PlayerEntity toRemove)
{
CleanPlayerEntity(toRemove);
if (IsPresentByID(toRemove.ID))
bool isPresent = IsPresentByID(toRemove.ID).Result;
if (isPresent)
{
db.Players.Remove(toRemove);
db.SaveChanges();
@ -118,7 +128,7 @@ namespace Data.EF.Players
/// <returns>the updated entity</returns>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
public PlayerEntity Update(PlayerEntity before, PlayerEntity after)
public Task<PlayerEntity> Update(PlayerEntity before, PlayerEntity after)
{
PlayerEntity[] args = { before, after };
@ -132,16 +142,14 @@ namespace Data.EF.Players
throw new ArgumentException("ID cannot be updated", nameof(after));
}
string beforeName = before.Name;
before.Name = after.Name;
EntityEntry ee = db.Players.Update(before);
db.SaveChanges();
return InternalUpdate(before, after);
before.Name = beforeName;
return (PlayerEntity)ee.Entity;
}
private async Task<PlayerEntity> InternalUpdate(PlayerEntity before, PlayerEntity after)
{
Remove(before);
return await Add(after);
}
/// <summary>
@ -151,14 +159,14 @@ namespace Data.EF.Players
/// <param name="ID">the ID to look for</param>
/// <returns>PlayerEntity with that ID</returns>
/// <exception cref="InvalidOperationException"></exception>
public PlayerEntity GetOneByID(Guid ID)
public async Task<PlayerEntity> GetOneByID(Guid ID)
{
return db.Players.First(p => p.ID == ID);
return await db.Players.FirstAsync(p => p.ID == ID);
}
public bool IsPresentByID(Guid ID)
public async Task<bool> IsPresentByID(Guid ID)
{
return db.Players.Where(p => p.ID == ID).Any();
return await db.Players.FirstOrDefaultAsync(p => p.ID == ID) is not null;
}
}
}

@ -1,8 +1,6 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Model;
using Model.Players;
using System.Runtime.Intrinsics.Arm;
namespace Data.EF.Players
{
@ -45,7 +43,7 @@ namespace Data.EF.Players
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
public PlayerEntity Add(PlayerEntity toAdd)
public Task<PlayerEntity> Add(PlayerEntity toAdd)
{
CleanPlayerEntity(toAdd);
@ -54,14 +52,21 @@ namespace Data.EF.Players
throw new ArgumentException("this username is already taken", nameof(toAdd));
}
EntityEntry ee = db.Players.Add(toAdd);
db.SaveChanges();
return InternalAdd(toAdd);
}
private async Task<PlayerEntity> InternalAdd(PlayerEntity toAdd)
{
EntityEntry ee = await db.Players.AddAsync(toAdd);
await db.SaveChangesAsync();
return (PlayerEntity)ee.Entity;
}
public IEnumerable<PlayerEntity> GetAll()
public async Task<IEnumerable<PlayerEntity>> GetAll()
{
return db.Players.AsEnumerable();
List<PlayerEntity> players = new();
await Task.Run(() => players.AddRange(db.Players));
return players.AsEnumerable();
}
/// <summary>
@ -72,25 +77,30 @@ namespace Data.EF.Players
/// <exception cref="ArgumentException"></exception>
/// <exception cref="InvalidOperationException"></exception>
/// <returns></returns>
public PlayerEntity GetOneByName(string name)
public Task<PlayerEntity> GetOneByName(string name)
{
if (string.IsNullOrWhiteSpace(name))
{
throw new ArgumentException("Name property should not be null or whitespace", nameof(name));
}
name = name.Trim();
return db.Players.Where(p => p.Name == name).First();
return InternalGetOneByName(name);
}
public bool IsPresentByName(string name)
private async Task<PlayerEntity> InternalGetOneByName(string name)
{
return await db.Players.Where(p => p.Name == name).FirstAsync();
}
public async Task<bool> IsPresentByName(string name)
{
if (string.IsNullOrWhiteSpace(name))
{
return false;
}
name = name.Trim();
return db.Players.Where(p => p.Name == name).Any();
return await db.Players.Where(p => p.Name == name).FirstOrDefaultAsync() is not null;
}
/// <summary>
@ -102,8 +112,8 @@ namespace Data.EF.Players
public void Remove(PlayerEntity toRemove)
{
CleanPlayerEntity(toRemove);
if (IsPresentByID(toRemove.ID))
bool isPresent = IsPresentByID(toRemove.ID).Result;
if (isPresent)
{
db.Players.Remove(toRemove);
db.SaveChanges();
@ -118,7 +128,7 @@ namespace Data.EF.Players
/// <returns>the updated entity</returns>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
public PlayerEntity Update(PlayerEntity before, PlayerEntity after)
public Task<PlayerEntity> Update(PlayerEntity before, PlayerEntity after)
{
PlayerEntity[] args = { before, after };
@ -132,16 +142,14 @@ namespace Data.EF.Players
throw new ArgumentException("ID cannot be updated", nameof(after));
}
string beforeName = before.Name;
before.Name = after.Name;
EntityEntry ee = db.Players.Update(before);
db.SaveChanges();
return InternalUpdate(before, after);
before.Name = beforeName;
return (PlayerEntity)ee.Entity;
}
private async Task<PlayerEntity> InternalUpdate(PlayerEntity before, PlayerEntity after)
{
Remove(before);
return await Add(after);
}
/// <summary>
@ -151,14 +159,14 @@ namespace Data.EF.Players
/// <param name="ID">the ID to look for</param>
/// <returns>PlayerEntity with that ID</returns>
/// <exception cref="InvalidOperationException"></exception>
public PlayerEntity GetOneByID(Guid ID)
public async Task<PlayerEntity> GetOneByID(Guid ID)
{
return db.Players.First(p => p.ID == ID);
return await db.Players.FirstAsync(p => p.ID == ID);
}
public bool IsPresentByID(Guid ID)
public async Task<bool> IsPresentByID(Guid ID)
{
return db.Players.Where(p => p.ID == ID).Any();
return await db.Players.FirstOrDefaultAsync(p => p.ID == ID) is not null;
}
}
}

@ -4,6 +4,6 @@ namespace Data
{
public interface ILoader
{
public MasterOfCeremonies LoadApp();
public Task<MasterOfCeremonies> LoadApp();
}
}

@ -8,15 +8,15 @@ namespace Data
{
public class Stub : ILoader
{
public MasterOfCeremonies LoadApp()
public async Task<MasterOfCeremonies> LoadApp()
{
MasterOfCeremonies gr = new(new PlayerManager(), new DiceGroupManager(), new GameManager());
Player player1 = new("Alice(Old Stub)"), player2 = new("Bob(Old Stub)"), player3 = new("Clyde(Old Stub)");
gr.GlobalPlayerManager.Add(player1);
gr.GlobalPlayerManager.Add(player2);
gr.GlobalPlayerManager.Add(player3);
await gr.GlobalPlayerManager.Add(player1);
await gr.GlobalPlayerManager.Add(player2);
await gr.GlobalPlayerManager.Add(player3);
List<Die> monopolyDice = new();
@ -63,32 +63,32 @@ namespace Data
dndDice.Add(new NumberDie(d20Faces[0], d20Faces[1..]));
gr.DiceGroupManager.Add(new KeyValuePair<string, IEnumerable<Die>>(dndName, dndDice.AsEnumerable()));
gr.DiceGroupManager.Add(new KeyValuePair<string, IEnumerable<Die>>(monopolyName, monopolyDice.AsEnumerable()));
await gr.DiceGroupManager.Add(new KeyValuePair<string, IEnumerable<Die>>(dndName, dndDice.AsEnumerable()));
await gr.DiceGroupManager.Add(new KeyValuePair<string, IEnumerable<Die>>(monopolyName, monopolyDice.AsEnumerable()));
string game1 = "Forgotten Realms", game2 = "4e", game3 = "The Coopers";
gr.GameManager.Add(new(game1, new PlayerManager(), dndDice.AsEnumerable()));
gr.GameManager.Add(new(game2, new PlayerManager(), dndDice.AsEnumerable()));
gr.GameManager.Add(new(game3, new PlayerManager(), monopolyDice.AsEnumerable()));
await gr.GameManager.Add(new(game1, new PlayerManager(), dndDice.AsEnumerable()));
await gr.GameManager.Add(new(game2, new PlayerManager(), dndDice.AsEnumerable()));
await gr.GameManager.Add(new(game3, new PlayerManager(), monopolyDice.AsEnumerable()));
gr.GameManager.GetOneByName(game1).PlayerManager.Add(player1);
gr.GameManager.GetOneByName(game1).PlayerManager.Add(player2);
await (await gr.GameManager.GetOneByName(game1)).PlayerManager.Add(player1);
await (await gr.GameManager.GetOneByName(game1)).PlayerManager.Add(player2);
gr.GameManager.GetOneByName(game2).PlayerManager.Add(player1);
gr.GameManager.GetOneByName(game2).PlayerManager.Add(player2);
gr.GameManager.GetOneByName(game2).PlayerManager.Add(player3);
await (await gr.GameManager.GetOneByName(game2)).PlayerManager.Add(player1);
await (await gr.GameManager.GetOneByName(game2)).PlayerManager.Add(player2);
await (await gr.GameManager.GetOneByName(game2)).PlayerManager.Add(player3);
gr.GameManager.GetOneByName(game3).PlayerManager.Add(player1);
gr.GameManager.GetOneByName(game3).PlayerManager.Add(player3);
await (await gr.GameManager.GetOneByName(game3)).PlayerManager.Add(player1);
await (await gr.GameManager.GetOneByName(game3)).PlayerManager.Add(player3);
foreach (Game game in gr.GameManager.GetAll())
foreach (Game game in gr.GameManager.GetAll()?.Result)
{
for (int i = 0; i < 10; i++)
{
Player currentPlayer = game.GetWhoPlaysNow();
Player currentPlayer = await game.GetWhoPlaysNow();
game.PerformTurn(currentPlayer);
game.PrepareNextPlayer(currentPlayer);
await game.PrepareNextPlayer(currentPlayer);
}
}

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Model.Dice
{
@ -8,7 +9,7 @@ namespace Model.Dice
{
private readonly Dictionary<string, IEnumerable<Die>> diceGroups = new();
public KeyValuePair<string, IEnumerable<Die>> Add(KeyValuePair<string, IEnumerable<Die>> toAdd)
public Task<KeyValuePair<string, IEnumerable<Die>>> Add(KeyValuePair<string, IEnumerable<Die>> toAdd)
{
if (string.IsNullOrWhiteSpace(toAdd.Key))
{
@ -20,20 +21,20 @@ namespace Model.Dice
throw new ArgumentException("this username is already taken", nameof(toAdd));
}
diceGroups.Add(toAdd.Key.Trim(), toAdd.Value);
return toAdd;
return Task.FromResult(toAdd);
}
public IEnumerable<KeyValuePair<string, IEnumerable<Die>>> GetAll()
public Task<IEnumerable<KeyValuePair<string, IEnumerable<Die>>>> GetAll()
{
return diceGroups.AsEnumerable();
return Task.FromResult(diceGroups.AsEnumerable());
}
public KeyValuePair<string, IEnumerable<Die>> GetOneByID(Guid ID)
public Task<KeyValuePair<string, IEnumerable<Die>>> GetOneByID(Guid ID)
{
throw new NotImplementedException();
}
public KeyValuePair<string, IEnumerable<Die>> GetOneByName(string name)
public Task<KeyValuePair<string, IEnumerable<Die>>> GetOneByName(string name)
{
// les groupes de dés nommés :
// ils sont case-sensistive, mais "mon jeu" == "mon jeu " == " mon jeu"
@ -41,10 +42,7 @@ namespace Model.Dice
{
throw new ArgumentNullException(nameof(name), "param should not be null or empty");
}
else
{
return new KeyValuePair<string, IEnumerable<Die>>(name, diceGroups[name]);
}
return Task.FromResult(new KeyValuePair<string, IEnumerable<Die>>(name, diceGroups[name]));
}
public void Remove(KeyValuePair<string, IEnumerable<Die>> toRemove)
@ -67,7 +65,7 @@ namespace Model.Dice
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ArgumentNullException"></exception>
public KeyValuePair<string, IEnumerable<Die>> Update(KeyValuePair<string, IEnumerable<Die>> before, KeyValuePair<string, IEnumerable<Die>> after)
public Task<KeyValuePair<string, IEnumerable<Die>>> Update(KeyValuePair<string, IEnumerable<Die>> before, KeyValuePair<string, IEnumerable<Die>> after)
{
// pas autorisé de changer les dés, juste le nom
if (!before.Value.Equals(after.Value))
@ -79,8 +77,8 @@ namespace Model.Dice
throw new ArgumentNullException(nameof(before), "dice group name should not be null or empty");
}
diceGroups.Remove(before.Key);
diceGroups.Add(after.Key, after.Value);
return after;
Add(after);
return Task.FromResult(after);
}
}

@ -18,11 +18,5 @@
Value = value;
StringValue = value.ToString();
}
protected Face(T value, string stringValue)
{
Value = value;
StringValue = stringValue;
}
}
}

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Model.Games
{
@ -112,13 +113,13 @@ namespace Model.Games
/// </summary>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public Player GetWhoPlaysNow()
public async Task<Player> GetWhoPlaysNow()
{
if (!PlayerManager.GetAll().Any())
if (!(await PlayerManager.GetAll()).Any())
{
throw new MemberAccessException("you are exploring an empty collection\nthis should not have happened");
}
return PlayerManager.GetAll().ElementAt(nextIndex);
return (await PlayerManager.GetAll()).ElementAt(nextIndex);
}
/// <summary>
@ -128,9 +129,9 @@ namespace Model.Games
/// <exception cref="MemberAccessException"></exception>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
public void PrepareNextPlayer(Player current)
public async Task PrepareNextPlayer(Player current)
{
IEnumerable<Player> players = PlayerManager.GetAll();
IEnumerable<Player> players = await PlayerManager.GetAll();
if (!players.Any())
{
throw new MemberAccessException("you are exploring an empty collection\nthis should not have happened");
@ -179,7 +180,7 @@ namespace Model.Games
sb.Append($"Game: {Name}");
sb.Append("\nPlayers:");
foreach (Player player in PlayerManager.GetAll())
foreach (Player player in PlayerManager.GetAll()?.Result)
{
sb.Append($" {player.ToString()}");
}

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Model.Games
{
@ -20,7 +21,7 @@ namespace Model.Games
/// gets an unmodifiable collection of the games
/// </summary>
/// <returns>unmodifiable collection of the games</returns>
public IEnumerable<Game> GetAll() => games.AsEnumerable();
public Task<IEnumerable<Game>> GetAll() => Task.FromResult(games.AsEnumerable());
/// <summary>
/// finds the game with that name and returns it
@ -29,12 +30,11 @@ namespace Model.Games
/// </summary>
/// <param name="name">a games's name</param>
/// <returns>game with said name, <em>or null</em> if no such game was found</returns>
public Game GetOneByName(string name)
public Task<Game> GetOneByName(string name)
{
if (!string.IsNullOrWhiteSpace(name))
{
Game result = games.FirstOrDefault(g => g.Name == name);
return result; // may return null
return Task.FromResult(games.FirstOrDefault(g => g.Name == name)); // may return null
}
throw new ArgumentException("param should not be null or blank", nameof(name));
}
@ -45,7 +45,7 @@ namespace Model.Games
/// <param name="ID"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public Game GetOneByID(Guid ID)
public Task<Game> GetOneByID(Guid ID)
{
throw new NotImplementedException();
}
@ -54,7 +54,7 @@ namespace Model.Games
/// saves a given game -- does not allow copies yet: if a game with the same name exists, it is overwritten
/// </summary>
/// <param name="toAdd">a game to save</param>
public Game Add(Game toAdd)
public Task<Game> Add(Game toAdd)
{
if (toAdd is null)
{
@ -64,7 +64,7 @@ namespace Model.Games
games.Remove(games.FirstOrDefault(g => g.Name == toAdd.Name));
// will often be an update: if game with that name exists, it is removed, else, nothing happens above
games.Add(toAdd);
return toAdd;
return Task.FromResult(toAdd);
}
/// <summary>
@ -88,7 +88,7 @@ namespace Model.Games
/// <param name="after">new game</param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public Game Update(Game before, Game after)
public Task<Game> Update(Game before, Game after)
{
Game[] args = { before, after };
@ -103,7 +103,7 @@ namespace Model.Games
}
}
Remove(before);
return Add(after);
return (Add(after));
}
}
}

@ -1,6 +1,7 @@
using Model.Dice;
using Model.Players;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Model.Games
{
@ -24,21 +25,21 @@ namespace Model.Games
/// <param name="playerManager"></param>
/// <param name="dice"></param>
/// <returns></returns>
public Game StartNewGame(string name, IManager<Player> playerManager, IEnumerable<Die> dice)
public async Task<Game> StartNewGame(string name, IManager<Player> playerManager, IEnumerable<Die> dice)
{
Game game = new(name, playerManager, dice);
return GameManager.Add(game);
return await GameManager.Add(game);
}
/// <summary>
/// plays one turn of the game
/// </summary>
/// <param name="game">the game from which a turn will be played</param>
public static void PlayGame(Game game)
public static async Task PlayGame(Game game)
{
Player current = game.GetWhoPlaysNow();
Player current = await game.GetWhoPlaysNow();
game.PerformTurn(current);
game.PrepareNextPlayer(current);
await game.PrepareNextPlayer(current);
}
}

@ -1,14 +1,21 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Model
{
public interface IManager<T>
{
public T Add(T toAdd);
public T GetOneByName(string name);
public T GetOneByID(Guid ID);
public IEnumerable<T> GetAll();
public T Update(T before, T after);
public Task<T> Add(T toAdd);
public Task<T> GetOneByName(string name);
public Task<T> GetOneByID(Guid ID);
public Task<IEnumerable<T>> GetAll();
public Task<T> Update(T before, T after);
public void Remove(T toRemove);
}
}

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Model.Players
{
@ -20,7 +21,7 @@ namespace Model.Players
/// </summary>
/// <param name="toAdd">player to be added</param>
/// <returns>added player</returns>
public Player Add(Player toAdd)
public Task<Player> Add(Player toAdd)
{
if (toAdd is null)
{
@ -31,25 +32,27 @@ namespace Model.Players
throw new ArgumentException("this username is already taken", nameof(toAdd));
}
players.Add(toAdd);
return toAdd;
return Task.FromResult(toAdd);
}
/// <summary>
/// finds the player with that name and returns A COPY OF IT
/// <br/>
/// that copy does not belong to this manager's players, so it should not be modified
/// finds the player with that name and returns it
/// </summary>
/// <param name="name">a player's unique name</param>
/// <returns>player with said name, <em>or null</em> if no such player was found</returns>
public Player GetOneByName(string name)
public Task<Player> GetOneByName(string name)
{
if (!string.IsNullOrWhiteSpace(name))
if (string.IsNullOrWhiteSpace(name))
{
Player wanted = new(name);
Player result = players.FirstOrDefault(p => p.Equals(wanted));
return result is null ? null : new Player(result); // THIS IS A COPY (using a copy constructor)
throw new ArgumentException("param should not be null or blank", nameof(name));
}
throw new ArgumentException("param should not be null or blank", nameof(name));
Player result = players.FirstOrDefault(p => p.Name.ToUpper().Equals(name.ToUpper().Trim()));
if (result == null)
{
return Task.FromResult<Player>(null);
}
return Task.FromResult(result);
}
/// </summary>
@ -57,7 +60,7 @@ namespace Model.Players
/// so that the only way to modify the collection of players is to use this class's methods
/// </summary>
/// <returns>a readonly enumerable of all this manager's players</returns>
public IEnumerable<Player> GetAll() => players.AsEnumerable();
public Task<IEnumerable<Player>> GetAll() => Task.FromResult(players.AsEnumerable());
/// <summary>
/// update a player from <paramref name="before"/> to <paramref name="after"/>
@ -65,7 +68,7 @@ namespace Model.Players
/// <param name="before">player to be updated</param>
/// <param name="after">player in the state that it needs to be in after the update</param>
/// <returns>updated player</returns>
public Player Update(Player before, Player after)
public Task<Player> Update(Player before, Player after)
{
Player[] args = { before, after };
@ -96,7 +99,7 @@ namespace Model.Players
players.Remove(toRemove);
}
public Player GetOneByID(Guid ID)
public Task<Player> GetOneByID(Guid ID)
{
throw new NotImplementedException();
}

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Tests.Data_UTs
{
public class DiceAppDbContextTest
{
}
}

@ -0,0 +1,49 @@
using Data.EF;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;
namespace Tests.Data_UTs
{
public class DiceAppDbContextWithStubTest
{
private readonly SqliteConnection connection = new("DataSource=:memory:");
private readonly DbContextOptions<DiceAppDbContext> options;
public DiceAppDbContextWithStubTest()
{
connection.Open();
options = new DbContextOptionsBuilder<DiceAppDbContext>()
.UseSqlite(connection)
.EnableSensitiveDataLogging()
.Options;
}
[Theory]
[InlineData("Alice")]
[InlineData("Bob")]
[InlineData("Clyde")]
[InlineData("Dahlia")]
public void TestDbStubContainsAll(string name)
{
// Arrange
using (DiceAppDbContextWithStub db = new(options))
{
db.Database.EnsureCreated();
// Assert
Assert.True(db.Players.Where(p => p.Name.Equals(name)).Any());
}
}
}
}

@ -2,17 +2,11 @@
using Data.EF.Players;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Model.Players;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;
using Xunit.Sdk;
namespace Tests.Data_UTs.Players
{
@ -33,32 +27,8 @@ namespace Tests.Data_UTs.Players
.Options;
}
[Theory]
[InlineData("Alice")]
[InlineData("Bob")]
[InlineData("Clyde")]
[InlineData("Dahlia")]
public void TestDbStubContainsAll(string name)
{
// Arrange
PlayerDbManager mgr;
// Act
using (DiceAppDbContextWithStub db = new(options))
{
db.Database.EnsureCreated();
mgr = new(db);
// Assert
Assert.True(mgr.IsPresentByName(name));
}
}
[Fact]
public void TestConstructorWhenGivenContextThenConstructs()
public async Task TestConstructorWhenGivenContextThenConstructs()
{
// Arrange
@ -72,7 +42,7 @@ namespace Tests.Data_UTs.Players
// Assert
Assert.Equal(new Collection<PlayerEntity>(), mgr.GetAll());
Assert.Equal(new Collection<PlayerEntity>(), await mgr.GetAll());
}
}
@ -93,7 +63,7 @@ namespace Tests.Data_UTs.Players
}
[Fact]
public void TestAddWhenValidThenValid()
public async Task TestAddWhenValidThenValid()
{
// Arrange
@ -107,8 +77,8 @@ namespace Tests.Data_UTs.Players
{
db.Database.EnsureCreated();
mgr = new(db);
mgr.Add(new PlayerEntity() { Name = expectedName });
mgr.Add(new PlayerEntity() { Name = "whatever" });
await mgr.Add(new PlayerEntity() { Name = expectedName });
await mgr.Add(new PlayerEntity() { Name = "whatever" });
// mgr takes care of the SaveChange() calls internally
// we might use Units of Work later, to optimize our calls to DB
}
@ -119,14 +89,14 @@ namespace Tests.Data_UTs.Players
{
db.Database.EnsureCreated();
mgr = new(db);
Assert.Equal(expectedName, mgr.GetOneByName(expectedName).Name);
Assert.Equal(expectedCount, mgr.GetAll().Count());
Assert.Equal(expectedName, (await mgr.GetOneByName(expectedName)).Name);
Assert.Equal(expectedCount, (await mgr.GetAll()).Count());
}
}
[Fact]
public void TestAddWhenPreExistentThenException()
public async Task TestAddWhenPreExistentThenException()
{
// Arrange
@ -140,12 +110,12 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated();
mgr = new(db);
mgr.Add(new PlayerEntity() { Name = name });
void action() => mgr.Add(new PlayerEntity() { Name = name });
await mgr.Add(new PlayerEntity() { Name = name });
async Task actionAsync() => await mgr.Add(new PlayerEntity() { Name = name });
// Assert
Assert.Throws<ArgumentException>(action);
await Assert.ThrowsAsync<ArgumentException>(actionAsync);
}
}
@ -164,11 +134,11 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated();
mgr = new(db);
void action() => mgr.Add(null);
async Task actionAsync() => await mgr.Add(null);
// Assert
Assert.Throws<ArgumentNullException>(action);
Assert.ThrowsAsync<ArgumentNullException>(actionAsync);
}
}
@ -190,11 +160,11 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated();
mgr = new(db);
void action() => mgr.Add(new PlayerEntity() { Name = name });
async Task actionAsync() => await mgr.Add(new PlayerEntity() { Name = name });
// Assert
Assert.Throws<ArgumentException>(action);
Assert.ThrowsAsync<ArgumentException>(actionAsync);
}
}
@ -202,7 +172,7 @@ namespace Tests.Data_UTs.Players
[InlineData(" ")]
[InlineData(null)]
[InlineData("")]
public void TestGetOneByNameWhenInvalidThenException(string name)
public async Task TestGetOneByNameWhenInvalidThenException(string name)
{
// Arrange
@ -215,14 +185,14 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated();
mgr = new(db);
mgr.Add(new() { Name = "Ernesto" });
mgr.Add(new() { Name = "Basil" });
await mgr.Add(new() { Name = "Ernesto" });
await mgr.Add(new() { Name = "Basil" });
void action() => mgr.GetOneByName(name);
async Task actionAsync() => await mgr.GetOneByName(name);
// Assert
Assert.Throws<ArgumentException>(action);
await Assert.ThrowsAsync<ArgumentException>(actionAsync);
}
}
@ -230,7 +200,7 @@ namespace Tests.Data_UTs.Players
[InlineData("Caroline")]
[InlineData("Caroline ")]
[InlineData(" Caroline")]
public void TestGetOneByNameWhenValidAndExistsThenGetsIt(string name)
public async Task TestGetOneByNameWhenValidAndExistsThenGetsIt(string name)
{
// Arrange
@ -246,8 +216,8 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated();
mgr = new(db);
mgr.Add(expected);
mgr.Add(new() { Name = "Philip" });
await mgr.Add(expected);
await mgr.Add(new() { Name = "Philip" });
}
// Assert
@ -256,13 +226,13 @@ namespace Tests.Data_UTs.Players
{
db.Database.EnsureCreated();
mgr = new(db);
actual = mgr.GetOneByName(name);
actual = await mgr.GetOneByName(name);
Assert.Equal(expected, actual);
}
}
[Fact]
public void TestGetOneByNameWhenValidAndNotExistsThenException()
public async Task TestGetOneByNameWhenValidAndNotExistsThenException()
{
// Arrange
@ -276,19 +246,19 @@ namespace Tests.Data_UTs.Players
mgr = new(db);
//mgr.Add(expected);
mgr.Add(new() { Name = "Brett" });
mgr.Add(new() { Name = "Noah" });
await mgr.Add(new() { Name = "Brett" });
await mgr.Add(new() { Name = "Noah" });
void action() => mgr.GetOneByName("*r^a*éàru é^à");
async Task actionAsync() => await mgr.GetOneByName("*r^a*éàru é^à");
// Assert
Assert.Throws<InvalidOperationException>(action);
await Assert.ThrowsAsync<InvalidOperationException>(actionAsync);
}
}
[Fact]
public void TestIsPresentByNameWhenValidAndExistsThenTrue()
public async Task TestIsPresentByNameWhenValidAndExistsThenTrue()
{
// Arrange
@ -302,8 +272,8 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated();
mgr = new(db);
mgr.Add(new() { Name = "Philip" });
mgr.Add(new() { Name = name });
await mgr.Add(new() { Name = "Philip" });
await mgr.Add(new() { Name = name });
}
// Assert
@ -313,7 +283,7 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated();
mgr = new(db);
Assert.True(mgr.IsPresentByName(name));
Assert.True(await mgr.IsPresentByName(name));
}
}
@ -321,8 +291,8 @@ namespace Tests.Data_UTs.Players
[InlineData("")]
[InlineData(" ")]
[InlineData(null)]
[InlineData("Barbara")]
public void TestIsPresentByNameWhenInvalidOrNonExistentThenFalse(string name)
[InlineData("nowaythatthisnameisalreadyinourdatabase")]
public async Task TestIsPresentByNameWhenInvalidOrNonExistentThenFalse(string name)
{
// Arrange
@ -335,8 +305,8 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated();
mgr = new(db);
mgr.Add(new() { Name = "Herman" });
mgr.Add(new() { Name = "Paulo" });
await mgr.Add(new() { Name = "Herman" });
await mgr.Add(new() { Name = "Paulo" });
}
// Assert
@ -346,7 +316,7 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated();
mgr = new(db);
Assert.False(mgr.IsPresentByName(name));
Assert.False(await mgr.IsPresentByName(name));
}
}
@ -379,46 +349,38 @@ namespace Tests.Data_UTs.Players
PlayerDbManager mgr;
PlayerEntity toRemove = new() { Name = "Filibert" };
using (DiceAppDbContext db = new(options))
{
db.Database.EnsureCreated();
mgr = new(db);
PlayerEntity toRemove = new() { ID = Guid.NewGuid(), Name = "Please!" };
mgr.Add(new() { Name = "Xavier" });
mgr.Add(toRemove);
}
// Act
using (DiceAppDbContext db = new(options))
using (DiceAppDbContextWithStub db = new(options))
{
db.Database.EnsureCreated();
mgr = new(db);
mgr.Add(toRemove); // calls SaveChangesAsync()
mgr.Remove(toRemove);
}
// Assert
using (DiceAppDbContext db = new(options))
using (DiceAppDbContextWithStub db = new(options))
{
db.Database.EnsureCreated();
mgr = new(db);
Assert.DoesNotContain(toRemove, mgr.GetAll());
Assert.DoesNotContain(toRemove, db.Players);
}
}
[Fact]
public void TestRemoveWhenNonExistentThenStillNonExistent()
public async Task TestRemoveWhenNonExistentThenStillNonExistent()
{
// Arrange
PlayerDbManager mgr;
PlayerEntity toRemove = new() { Name = "Filibert" };
PlayerEntity toRemove = new() { ID = Guid.NewGuid(), Name = "Filibert" };
// Act
@ -427,7 +389,7 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated();
mgr = new(db);
mgr.Add(new() { Name = "Bert" });
await mgr.Add(new() { ID = Guid.NewGuid(), Name = "Bert" });
mgr.Remove(toRemove);
}
@ -438,14 +400,14 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated();
mgr = new(db);
Assert.DoesNotContain(toRemove, mgr.GetAll());
Assert.DoesNotContain(toRemove, await mgr.GetAll());
}
}
[Theory]
[InlineData("filiBert")]
[InlineData("Bertrand")]
public void TestUpdateWhenValidThenUpdates(string name)
public async Task TestUpdateWhenValidThenUpdates(string name)
{
// Arrange
@ -462,8 +424,8 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated();
mgr = new(db);
mgr.Add(before);
mgr.Update(before, after);
await mgr.Add(before);
await mgr.Update(before, after);
}
// Assert
@ -473,8 +435,8 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated();
mgr = new(db);
Assert.DoesNotContain(before, mgr.GetAll());
Assert.Contains(after, mgr.GetAll());
Assert.DoesNotContain(before, await mgr.GetAll());
Assert.Contains(after, await mgr.GetAll());
}
}
@ -482,7 +444,7 @@ namespace Tests.Data_UTs.Players
[InlineData("Valerie")]
[InlineData("Valerie ")]
[InlineData(" Valerie")]
public void TestUpdateWhenSameThenKeepsAndWorks(string name)
public async Task TestUpdateWhenSameThenKeepsAndWorks(string name)
{
// Arrange
@ -500,8 +462,8 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated();
mgr = new(db);
mgr.Add(before);
mgr.Update(before, after);
await mgr.Add(before);
await mgr.Update(before, after);
}
// Assert
@ -511,14 +473,14 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated();
mgr = new(db);
Assert.Contains(before, mgr.GetAll());
Assert.Contains(after, mgr.GetAll());
Assert.Contains(before, await mgr.GetAll());
Assert.Contains(after, await mgr.GetAll());
}
}
[Fact]
public void TestUpdateWhenNewIDThenException()
public async Task TestUpdateWhenNewIDThenException()
{
// Arrange
@ -534,12 +496,12 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated();
mgr = new(db);
mgr.Add(before);
void action() => mgr.Update(before, after);
await mgr.Add(before);
async Task actionAsync() => await mgr.Update(before, after);
// Assert
Assert.Throws<ArgumentException>(action);
await Assert.ThrowsAsync<ArgumentException>(actionAsync);
}
}
@ -547,7 +509,7 @@ namespace Tests.Data_UTs.Players
[InlineData("")]
[InlineData(" ")]
[InlineData(null)]
public void TestUpdateWhenInvalidThenException(string name)
public async Task TestUpdateWhenInvalidThenException(string name)
{
// Arrange
@ -564,17 +526,17 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated();
mgr = new(db);
mgr.Add(before);
void action() => mgr.Update(before, after);
await mgr.Add(before);
async Task actionAsync() => await mgr.Update(before, after);
// Assert
Assert.Throws<ArgumentException>(action);
await Assert.ThrowsAsync<ArgumentException>(actionAsync);
}
}
[Fact]
public void TestUpdateWhenNullThenException()
public async Task TestUpdateWhenNullThenException()
{
// Arrange
@ -589,17 +551,17 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated();
mgr = new(db);
mgr.Add(before);
void action() => mgr.Update(before, null);
await mgr.Add(before);
async Task actionAsync() => await mgr.Update(before, null);
// Assert
Assert.Throws<ArgumentNullException>(action);
await Assert.ThrowsAsync<ArgumentNullException>(actionAsync);
}
}
[Fact]
public void TestGetOneByIDWhenExistsThenGetsIt()
public async Task TestGetOneByIDWhenExistsThenGetsIt()
{
// Arrange
@ -616,7 +578,7 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated();
mgr = new(db);
mgr.Add(expected);
await mgr.Add(expected);
}
// Assert
@ -625,13 +587,13 @@ namespace Tests.Data_UTs.Players
{
db.Database.EnsureCreated();
mgr = new(db);
actual = mgr.GetOneByID(id);
actual = await mgr.GetOneByID(id);
Assert.Equal(expected, actual);
}
}
[Fact]
public void TestGetOneByIDWhenNotExistsThenException()
public async Task TestGetOneByIDWhenNotExistsThenExceptionAsync()
{
// Arrange
@ -649,18 +611,18 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated();
mgr = new(db);
mgr.Add(expected);
await mgr.Add(expected);
void action() => mgr.GetOneByID(otherId);
async Task actionAsync() => await mgr.GetOneByID(otherId);
// Assert
Assert.Throws<InvalidOperationException>(action);
await Assert.ThrowsAsync<InvalidOperationException>(actionAsync);
}
}
[Fact]
public void TestIsPresentbyIdWhenExistsThenTrue()
public async Task TestIsPresentbyIdWhenExistsThenTrue()
{
// Arrange
@ -674,7 +636,7 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated();
mgr = new(db);
mgr.Add(new() { ID = id, Name = "Bobby" });
await mgr.Add(new() { ID = id, Name = "Bobby" });
}
// Assert
@ -684,12 +646,12 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated();
mgr = new(db);
Assert.True(mgr.IsPresentByID(id));
Assert.True(await mgr.IsPresentByID(id));
}
}
[Fact]
public void TestIsPresentbyIdWhenExistsThenFalse()
public async Task TestIsPresentbyIdWhenNotExistsThenFalse()
{
// Arrange
@ -698,6 +660,9 @@ namespace Tests.Data_UTs.Players
Guid otherId = Guid.NewGuid();
PlayerEntity presentEntity;
PlayerEntity absentEntity;
// Act
using (DiceAppDbContext db = new(options))
@ -705,7 +670,10 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated();
mgr = new(db);
mgr.Add(new() { ID = id, Name = "Victor" });
presentEntity = new() { ID = id, Name = "Victor" };
await mgr.Add(presentEntity);
absentEntity = new() { ID = otherId, Name = "Victor" };
}
// Assert
@ -715,7 +683,7 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated();
mgr = new(db);
Assert.False(mgr.IsPresentByID(otherId));
Assert.DoesNotContain(absentEntity, db.Players);
}
}
}

@ -9,44 +9,45 @@ using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tests.Data_UTs.Games;
using Xunit;
namespace Tests.Model_UTs.Games
{
public class GameManagerTest
{
private readonly MasterOfCeremonies stubGameRunner = new Stub().LoadApp();
private readonly MasterOfCeremonies stubGameRunner = new Stub().LoadApp()?.Result;
[Fact]
public void TestConstructorReturnsEmptyEnumerable()
public async Task TestConstructorReturnsEmptyEnumerableAsync()
{
// Arrange
GameManager gm = new();
IEnumerable<Game> expected;
IEnumerable<Game> actual;
// Act
// Act
expected = new Collection<Game>();
actual = gm.GetAll();
actual = await gm.GetAll();
// Assert
Assert.Equal(expected, actual);
}
[Fact]
public void TestAddWhenGamesThenDoAddAndReturnGames()
public async Task TestAddWhenGamesThenDoAddAndReturnGamesAsync()
{
// Arrange
GameManager gm = new();
Game game1 = stubGameRunner.GameManager.GetAll().First();
Game game2 = stubGameRunner.GameManager.GetAll().Last();
Game game1 = (await stubGameRunner.GameManager.GetAll()).First();
Game game2 = (await stubGameRunner.GameManager.GetAll()).Last();
// Act
IEnumerable<Game> expected = new List<Game>() { game1, game2 }.AsEnumerable();
IEnumerable<Game> actual = new List<Game>()
{
gm.Add(game1),
gm.Add(game2)
await gm.Add(game1),
await gm.Add(game2)
};
// Assert
@ -54,17 +55,17 @@ namespace Tests.Model_UTs.Games
}
[Fact]
public void TestAddWhenNullThenThrowsException()
public async Task TestAddWhenNullThenThrowsException()
{
// Arrange
GameManager gm = new();
// Act
void action() => gm.Add(null);// Add() returns the added element if succesful
async Task actionAsync() => await gm.Add(null);// Add() returns the added element if succesful
// Assert
Assert.Throws<ArgumentNullException>(action);
Assert.DoesNotContain(null, stubGameRunner.GameManager.GetAll());
await Assert.ThrowsAsync<ArgumentNullException>(actionAsync);
Assert.DoesNotContain(null, await stubGameRunner.GameManager.GetAll());
}
[Fact]
@ -85,40 +86,40 @@ namespace Tests.Model_UTs.Games
[InlineData("")]
[InlineData(null)]
[InlineData(" ")]
public void TestGetOneByNameWhenInvalidThenThrowsException(string name)
public async Task TestGetOneByNameWhenInvalidThenThrowsExceptionAsync(string name)
{
// Arrange
GameManager gm = new();
// Act
void action() => gm.GetOneByName(name);
async Task actionAsync() => await gm.GetOneByName(name);
// Assert
Assert.Throws<ArgumentException>(action);
await Assert.ThrowsAsync<ArgumentException>(actionAsync);
}
[Fact]
public void TestGetOneByNameWhenValidButNotExistThenReturnNull()
public async Task TestGetOneByNameWhenValidButNotExistThenReturnNullAsync()
{
// Arrange
GameManager gm = new();
// Act
Game result = gm.GetOneByName("thereisbasicallynowaythatthisgamenamealreadyexists");
Game result = await gm.GetOneByName("thereisbasicallynowaythatthisgamenamealreadyexists");
// Assert
Assert.Null(result);
}
[Fact]
public void TestGetOneByNameWhenValidThenReturnGame()
public async Task TestGetOneByNameWhenValidThenReturnGameAsync()
{
// Arrange
GameManager gm = new();
Game game = stubGameRunner.GameManager.GetAll().First();
Game game = (await stubGameRunner.GameManager.GetAll()).First();
// Act
Game actual = gm.Add(game);
Game actual = await gm.Add(game);
Game expected = game;
// Assert
@ -126,19 +127,19 @@ namespace Tests.Model_UTs.Games
}
[Fact]
public void TestWhenRemoveExistsThenSucceeds()
public async Task TestWhenRemoveExistsThenSucceeds()
{
// Arrange
GameManager gm = new();
Game game = new("blargh", new PlayerManager(), stubGameRunner.GameManager.GetAll().First().Dice);
gm.Add(game);
Game game = new("blargh", new PlayerManager(), (await stubGameRunner.GameManager.GetAll()).First().Dice);
await gm.Add(game);
// Act
gm.Remove(game);
// Assert
Assert.DoesNotContain(game, gm.GetAll());
Assert.DoesNotContain(game, await gm.GetAll());
}
[Fact]
@ -155,46 +156,46 @@ namespace Tests.Model_UTs.Games
}
[Fact]
public void TestRemoveWhenGivenNonExistentThenFailsSilently()
public async Task TestRemoveWhenGivenNonExistentThenFailsSilentlyAsync()
{
// Arrange
IManager<Game> gm = stubGameRunner.GameManager;
Game notGame = new("blargh", new PlayerManager(), stubGameRunner.GameManager.GetAll().First().Dice);
IEnumerable<Game> expected = stubGameRunner.GameManager.GetAll();
Game notGame = new("blargh", new PlayerManager(), (await stubGameRunner.GameManager.GetAll()).First().Dice);
IEnumerable<Game> expected = await stubGameRunner.GameManager.GetAll();
// Act
gm.Remove(notGame);
IEnumerable<Game> actual = gm.GetAll();
IEnumerable<Game> actual = await gm.GetAll();
// Assert
Assert.Equal(actual, expected);
}
[Fact]
public void TestUpdateWhenValidThenSucceeds()
public async Task TestUpdateWhenValidThenSucceeds()
{
// Arrange
GameManager gm = new();
string oldName = "blargh";
string newName = "blargh2.0";
Game game = new(oldName, new PlayerManager(), stubGameRunner.GameManager.GetAll().First().Dice);
game.PlayerManager.Add(new("Alice"));
gm.Add(game);
Game game = new(oldName, new PlayerManager(), (await stubGameRunner.GameManager.GetAll()).First().Dice);
await game.PlayerManager.Add(new("Alice"));
await gm.Add(game);
Game oldGame = gm.GetAll().First();
Game oldGame = (await gm.GetAll()).First();
Game newGame = new(newName, oldGame.PlayerManager, oldGame.Dice);
// Act
int expectedSize = gm.GetAll().Count();
gm.Update(oldGame, newGame);
int actualSize = gm.GetAll().Count();
int expectedSize = (await gm.GetAll()).Count();
await gm.Update(oldGame, newGame);
int actualSize = (await gm.GetAll()).Count();
// Assert
Assert.NotEqual(oldName, newName);
Assert.DoesNotContain(oldGame, gm.GetAll());
Assert.Contains(newGame, gm.GetAll());
Assert.DoesNotContain(oldGame, await gm.GetAll());
Assert.Contains(newGame, await gm.GetAll());
Assert.Equal(expectedSize, actualSize);
}
@ -202,57 +203,57 @@ namespace Tests.Model_UTs.Games
[InlineData("")]
[InlineData(" ")]
[InlineData(null)]
public void TestUpdateWhenValidBeforeAndInvalidAfterThenDoesNotGo(string badName)
public async Task TestUpdateWhenValidBeforeAndInvalidAfterThenDoesNotGoAsync(string badName)
{
// Arrange
IManager<Game> gm = stubGameRunner.GameManager;
int expectedSize = gm.GetAll().Count();
Game oldGame = gm.GetAll().First();
int expectedSize = (await gm.GetAll()).Count();
Game oldGame = (await gm.GetAll()).First();
// Act
void action() => gm.Update(oldGame, new(badName, oldGame.PlayerManager, oldGame.Dice));
int actualSize = gm.GetAll().Count();
int actualSize = (await gm.GetAll()).Count();
// Assert
Assert.Throws<ArgumentException>(action); // thrown by constructor
Assert.Contains(oldGame, gm.GetAll()); // still there
Assert.Contains(oldGame, await gm.GetAll()); // still there
Assert.Equal(expectedSize, actualSize);
}
[Fact]
public void TestUpdateWhenValidBeforeAndNullAfterThenDoesNotGo()
public async Task TestUpdateWhenValidBeforeAndNullAfterThenDoesNotGoAsync()
{
// Arrange
IManager<Game> gm = stubGameRunner.GameManager;
int expectedSize = gm.GetAll().Count();
Game oldGame = gm.GetAll().First();
int expectedSize = (await gm.GetAll()).Count();
Game oldGame = (await gm.GetAll()).First();
// Act
void action() => gm.Update(oldGame, null);
int actualSize = gm.GetAll().Count();
async Task actionAsync() => await gm.Update(oldGame, null);
int actualSize = (await gm.GetAll()).Count();
// Assert
Assert.Throws<ArgumentNullException>(action); // thrown by constructor
Assert.Contains(oldGame, gm.GetAll()); // still there
await Assert.ThrowsAsync<ArgumentNullException>(actionAsync); // thrown by constructor
Assert.Contains(oldGame, await gm.GetAll()); // still there
Assert.True(expectedSize == actualSize);
}
[Fact]
public void TestUpdateDoesNotGoWithValidAfterAndNullBefore()
public async Task TestUpdateDoesNotGoWithValidAfterAndNullBefore()
{
// Arrange
IManager<Game> gm = stubGameRunner.GameManager;
int expectedSize = gm.GetAll().Count();
Game oldGame = gm.GetAll().First();
int expectedSize = (await gm.GetAll()).Count();
Game oldGame = (await gm.GetAll()).First();
// Act
void action() => gm.Update(null, new("newgamename", oldGame.PlayerManager, oldGame.Dice));
int actualSize = gm.GetAll().Count();
async Task actionAsync() => await gm.Update(null, new("newgamename", oldGame.PlayerManager, oldGame.Dice));
int actualSize = (await gm.GetAll()).Count();
// Assert
Assert.Throws<ArgumentNullException>(action); // thrown by constructor
Assert.Contains(oldGame, gm.GetAll()); // still there
await Assert.ThrowsAsync<ArgumentNullException>(actionAsync); // thrown by constructor
Assert.Contains(oldGame, await gm.GetAll()); // still there
Assert.True(expectedSize == actualSize);
}
@ -260,20 +261,20 @@ namespace Tests.Model_UTs.Games
[InlineData("")]
[InlineData(" ")]
[InlineData(null)]
public void TestUpdateWhenInvalidBeforeAndValidAfterThenDoesNotGo(string badName)
public async Task TestUpdateWhenInvalidBeforeAndValidAfterThenDoesNotGoAsync(string badName)
{
// Arrange
IManager<Game> gm = stubGameRunner.GameManager;
int expectedSize = gm.GetAll().Count();
Game oldGame = gm.GetAll().First();
int expectedSize = (await gm.GetAll()).Count();
Game oldGame = (await gm.GetAll()).First();
// Act
void action() => gm.Update(new(badName, oldGame.PlayerManager, oldGame.Dice), new("valid", oldGame.PlayerManager, oldGame.Dice));
int actualSize = gm.GetAll().Count();
int actualSize = (await gm.GetAll()).Count();
// Assert
Assert.Throws<ArgumentException>(action); // thrown by constructor
Assert.Contains(oldGame, gm.GetAll()); // still there
Assert.Contains(oldGame, await gm.GetAll()); // still there
Assert.True(expectedSize == actualSize);
}

@ -7,25 +7,25 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
namespace Tests.Model_UTs.Games
{
public class GameTest
{
private readonly MasterOfCeremonies stubMasterOfCeremonies = new Stub().LoadApp();
private readonly MasterOfCeremonies stubMasterOfCeremonies = new Stub().LoadApp()?.Result;
private static readonly string GAME_NAME = "my game";
private static readonly Player PLAYER_1 = new("Alice"), PLAYER_2 = new("Bob"), PLAYER_3 = new("Clyde");
private readonly IEnumerable<Die> DICE_1, DICE_2;
public GameTest()
{
DICE_1 = stubMasterOfCeremonies.DiceGroupManager.GetAll().First().Value;
DICE_2 = stubMasterOfCeremonies.DiceGroupManager.GetAll().Last().Value;
IEnumerable<KeyValuePair<string, IEnumerable<Die>>> diceGroups = stubMasterOfCeremonies.DiceGroupManager.GetAll()?.Result;
DICE_1 = diceGroups.First().Value;
DICE_2 = diceGroups.Last().Value;
}
[Fact]
public void TestNamePropertyGet()
{
@ -78,10 +78,14 @@ namespace Tests.Model_UTs.Games
}
[Fact]
public void TestGetHistory()
public async void TestGetHistory()
{
// Arrange
Dictionary<Die, Face> diceNFaces = (Dictionary<Die, Face>)stubMasterOfCeremonies.GameManager.GetAll().First().GetHistory().First().DiceNFaces;
Dictionary<Die, Face> diceNFaces =
(Dictionary<Die, Face>)(await stubMasterOfCeremonies.GameManager.GetAll())
.First()
.GetHistory()
.First().DiceNFaces;
Turn turn1 = Turn.CreateWithDefaultTime(PLAYER_1, diceNFaces);
Turn turn2 = Turn.CreateWithDefaultTime(PLAYER_2, diceNFaces); // yeah they rolled the same
@ -118,24 +122,24 @@ namespace Tests.Model_UTs.Games
}
[Fact]
public void TestPerformTurnDoesAddOneTurn()
public async Task TestPerformTurnDoesAddOneTurnAsync()
{
// Arrange
Game game = new(name: GAME_NAME,
playerManager: new PlayerManager(),
dice: DICE_1);
game.PlayerManager.Add(PLAYER_1);
game.PlayerManager.Add(PLAYER_2);
await game.PlayerManager.Add(PLAYER_1);
await game.PlayerManager.Add(PLAYER_2);
int n = 5;
Player currentPlayer;
for (int i = 0; i < n; i++)
{
currentPlayer = game.GetWhoPlaysNow();
currentPlayer = await game.GetWhoPlaysNow();
game.PerformTurn(currentPlayer);
game.PrepareNextPlayer(currentPlayer);
await game.PrepareNextPlayer(currentPlayer);
}
Debug.WriteLine(game);
@ -149,23 +153,23 @@ namespace Tests.Model_UTs.Games
}
[Fact]
public void TestGetWhoPlaysNowWhenValidThenCorrect()
public async Task TestGetWhoPlaysNowWhenValidThenCorrectAsync()
{
// Arrange
Game game = new(name: GAME_NAME,
playerManager: new PlayerManager(),
dice: DICE_1);
game.PlayerManager.Add(PLAYER_1);
game.PlayerManager.Add(PLAYER_2);
await game.PlayerManager.Add(PLAYER_1);
await game.PlayerManager.Add(PLAYER_2);
// Act
Player actual = game.GetWhoPlaysNow();
Player actual = await game.GetWhoPlaysNow();
Player expected = PLAYER_1;
game.PrepareNextPlayer(actual);
await game.PrepareNextPlayer(actual);
Player actual2 = game.GetWhoPlaysNow();
Player actual2 = await game.GetWhoPlaysNow();
Player expected2 = PLAYER_2;
// Assert
@ -183,10 +187,10 @@ namespace Tests.Model_UTs.Games
dice: DICE_1);
// Act
void action() => game.GetWhoPlaysNow(); // on an empty collection of players
async Task actionAsync() => await game.GetWhoPlaysNow(); // on an empty collection of players
// Assert
Assert.Throws<MemberAccessException>(action);
Assert.ThrowsAsync<MemberAccessException>(actionAsync);
}
[Fact]
@ -197,10 +201,10 @@ namespace Tests.Model_UTs.Games
playerManager: new PlayerManager(),
dice: DICE_1);
// Act
void action() => game.PrepareNextPlayer(PLAYER_1); // on an empty collection of players
async Task actionAsync() => await game.PrepareNextPlayer(PLAYER_1); // on an empty collection of players
// Assert
Assert.Throws<MemberAccessException>(action);
Assert.ThrowsAsync<MemberAccessException>(actionAsync);
}
[Fact]
@ -214,10 +218,10 @@ namespace Tests.Model_UTs.Games
game.PlayerManager.Add(PLAYER_1);
// Act
void action() => game.PrepareNextPlayer(null);
async Task actionAsync() => await game.PrepareNextPlayer(null);
// Assert
Assert.Throws<ArgumentNullException>(action);
Assert.ThrowsAsync<ArgumentNullException>(actionAsync);
}
[Fact]
@ -231,59 +235,59 @@ namespace Tests.Model_UTs.Games
game.PlayerManager.Add(PLAYER_2);
// Act
void action() => game.PrepareNextPlayer(PLAYER_3);
async Task actionAsync() => await game.PrepareNextPlayer(PLAYER_3);
// Assert
Assert.Throws<ArgumentException>(action);
Assert.ThrowsAsync<ArgumentException>(actionAsync);
}
[Fact]
public void TestPrepareNextPlayerWhenValidThenCorrectWithSeveralPlayers()
public async Task TestPrepareNextPlayerWhenValidThenCorrectWithSeveralPlayersAsync()
{
// Arrange
Game game = new(name: GAME_NAME,
playerManager: new PlayerManager(),
dice: DICE_2);
game.PlayerManager.Add(PLAYER_1);
game.PlayerManager.Add(PLAYER_2);
await game.PlayerManager.Add(PLAYER_1);
await game.PlayerManager.Add(PLAYER_2);
// Act
Player expected = PLAYER_2;
Assert.Equal(PLAYER_1, game.GetWhoPlaysNow());
game.PrepareNextPlayer(PLAYER_1);
Assert.Equal(PLAYER_1, await game.GetWhoPlaysNow());
await game.PrepareNextPlayer(PLAYER_1);
Player actual = game.GetWhoPlaysNow();
Player actual = await game.GetWhoPlaysNow();
// Assert
Assert.Equal(expected, actual);
}
[Fact]
public void TestPrepareNextPlayerWhenValidThenCorrectWithOnePlayer()
public async Task TestPrepareNextPlayerWhenValidThenCorrectWithOnePlayerAsync()
{
// Arrange
Game game = new(name: GAME_NAME,
playerManager: new PlayerManager(),
dice: DICE_1);
game.PlayerManager.Add(PLAYER_1);
await game.PlayerManager.Add(PLAYER_1);
// Act
Player expected = PLAYER_1;
Assert.Equal(PLAYER_1, game.GetWhoPlaysNow());
game.PrepareNextPlayer(PLAYER_1);
Assert.Equal(PLAYER_1, await game.GetWhoPlaysNow());
await game.PrepareNextPlayer(PLAYER_1);
Player actual = game.GetWhoPlaysNow();
Player actual = await game.GetWhoPlaysNow();
// Assert
Assert.Equal(expected, actual);
}
[Fact]
public void TestAddPlayerToGame()
public async Task TestAddPlayerToGameAsync()
{
// Arrange
Game game = new(name: GAME_NAME,
@ -292,14 +296,14 @@ namespace Tests.Model_UTs.Games
// Act
Player expected = PLAYER_1;
Player actual = game.PlayerManager.Add(PLAYER_1);
Player actual = await game.PlayerManager.Add(PLAYER_1);
// Assert
Assert.Equal(expected, actual);
}
[Fact]
public void TestGetPlayersFromGame()
public async Task TestGetPlayersFromGameAsync()
{
// Arrange
Game game = new(name: GAME_NAME,
@ -307,46 +311,46 @@ namespace Tests.Model_UTs.Games
dice: DICE_1);
// Act
Assert.Empty(game.PlayerManager.GetAll());
game.PlayerManager.Add(PLAYER_1);
Assert.Empty(await game.PlayerManager.GetAll());
await game.PlayerManager.Add(PLAYER_1);
// Assert
Assert.Single(game.PlayerManager.GetAll());
Assert.Single(await game.PlayerManager.GetAll());
}
[Fact]
public void TestUpdatePlayerInGame()
public async Task TestUpdatePlayerInGameAsync()
{
// Arrange
Game game = new(name: GAME_NAME,
playerManager: new PlayerManager(),
dice: DICE_2);
game.PlayerManager.Add(PLAYER_1);
await game.PlayerManager.Add(PLAYER_1);
// Act
Player expected = PLAYER_2;
Player actual = game.PlayerManager.Update(PLAYER_1, PLAYER_2);
Player actual = await game.PlayerManager.Update(PLAYER_1, PLAYER_2);
// Assert
Assert.Equal(expected, actual);
}
[Fact]
public void TestRemovePlayerFromGame()
public async Task TestRemovePlayerFromGameAsync()
{
// Arrange
Game game = new(name: GAME_NAME,
playerManager: new PlayerManager(),
dice: DICE_1);
game.PlayerManager.Add(PLAYER_1);
game.PlayerManager.Add(PLAYER_2);
await game.PlayerManager.Add(PLAYER_1);
await game.PlayerManager.Add(PLAYER_2);
game.PlayerManager.Remove(PLAYER_1);
// Act
IEnumerable<Player> expected = new List<Player>() { PLAYER_2 }.AsEnumerable();
IEnumerable<Player> actual = game.PlayerManager.GetAll();
IEnumerable<Player> actual = await game.PlayerManager.GetAll();
// Assert
Assert.Equal(expected, actual);

@ -5,24 +5,25 @@ using Model.Players;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
namespace Tests.Model_UTs.Games
{
public class MasterOfCeremoniesTest
{
private readonly MasterOfCeremonies stubMasterOfCeremonies = new Stub().LoadApp();
private readonly MasterOfCeremonies stubMasterOfCeremonies = new Stub().LoadApp()?.Result;
[Fact]
public void TestPlayGameWhenPlayThenAddNewTurnToHistory()
public async Task TestPlayGameWhenPlayThenAddNewTurnToHistoryAsync()
{
// Arrange
MasterOfCeremonies masterOfCeremonies = stubMasterOfCeremonies;
Game game = masterOfCeremonies.GameManager.GetAll().First();
Game game = (await masterOfCeremonies.GameManager.GetAll()).First();
// Act
int turnsBefore = game.GetHistory().Count();
MasterOfCeremonies.PlayGame(game);
await MasterOfCeremonies.PlayGame(game);
int turnsAfter = game.GetHistory().Count();
// Assert
@ -30,18 +31,29 @@ namespace Tests.Model_UTs.Games
}
[Fact]
public void TestStartNewGame()
public async Task TestStartNewGame()
{
// Arrange
MasterOfCeremonies masterOfCeremonies = stubMasterOfCeremonies;
string name = "blargh";
// Act
Assert.DoesNotContain(masterOfCeremonies.GameManager.GetOneByName(name), masterOfCeremonies.GameManager.GetAll());
masterOfCeremonies.StartNewGame(name, new PlayerManager(), stubMasterOfCeremonies.GameManager.GetAll().First().Dice);
Assert.DoesNotContain(
await masterOfCeremonies.GameManager.GetOneByName(name),
await masterOfCeremonies.GameManager.GetAll()
);
await masterOfCeremonies.StartNewGame(
name,
new PlayerManager(),
stubMasterOfCeremonies.GameManager.GetAll()?.Result.First().Dice
);
// Assert
Assert.Contains(masterOfCeremonies.GameManager.GetOneByName(name), masterOfCeremonies.GameManager.GetAll());
Assert.Contains(
await masterOfCeremonies.GameManager.GetOneByName(name),
await masterOfCeremonies.GameManager.GetAll()
);
}
}
}

@ -13,14 +13,15 @@ namespace Tests.Model_UTs.Games
public class TurnTest
{
private readonly MasterOfCeremonies stubMasterOfCeremonies = new Stub().LoadApp();
private readonly MasterOfCeremonies stubMasterOfCeremonies = new Stub().LoadApp()?.Result;
Dictionary<Die, Face> DICE_N_FACES_1, DICE_N_FACES_2;
public TurnTest()
{
DICE_N_FACES_1 = (Dictionary<Die, Face>)stubMasterOfCeremonies.GameManager.GetAll().First().GetHistory().First().DiceNFaces;
DICE_N_FACES_2 = (Dictionary<Die, Face>)stubMasterOfCeremonies.GameManager.GetAll().Last().GetHistory().Last().DiceNFaces;
DICE_N_FACES_1 = (Dictionary<Die, Face>)stubMasterOfCeremonies.GameManager.GetAll()?.Result.First().GetHistory().First().DiceNFaces;
DICE_N_FACES_2 = (Dictionary<Die, Face>)stubMasterOfCeremonies.GameManager.GetAll()?.Result.Last().GetHistory().Last().DiceNFaces;
}
[Fact]

@ -3,6 +3,7 @@ using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
namespace Tests.Model_UTs.Players
@ -10,7 +11,7 @@ namespace Tests.Model_UTs.Players
public class PlayerManagerTest
{
[Fact]
public void TestConstructorReturnsEmptyEnumerable()
public async Task TestConstructorReturnsEmptyEnumerableAsync()
{
// Arrange
PlayerManager playerManager = new();
@ -19,14 +20,14 @@ namespace Tests.Model_UTs.Players
// Act
expected = new Collection<Player>();
actual = playerManager.GetAll();
actual = await playerManager.GetAll();
// Assert
Assert.Equal(expected, actual);
}
[Fact]
public void TestAddIfPlayersThenDoAddAndReturnPlayers()
public async Task TestAddIfPlayersThenDoAddAndReturnPlayersAsync()
{
// Arrange
PlayerManager playerManager = new();
@ -37,8 +38,8 @@ namespace Tests.Model_UTs.Players
Collection<Player> expected = new() { alice, bob };
Collection<Player> actual = new()
{
playerManager.Add(alice),
playerManager.Add(bob)
await playerManager.Add(alice),
await playerManager.Add(bob)
};
// Assert
@ -46,7 +47,7 @@ namespace Tests.Model_UTs.Players
}
[Fact]
public void TestAddIfNullThrowsException()
public async Task TestAddIfNullThrowsException()
{
// Arrange
PlayerManager playerManager = new();
@ -54,26 +55,26 @@ namespace Tests.Model_UTs.Players
// Act
expected = null;
void action() => playerManager.Add(expected);// Add() returns the added element if succesful
async Task actionAsync() => await playerManager.Add(expected);// Add() returns the added element if succesful
// Assert
Assert.Null(expected);
Assert.Throws<ArgumentNullException>(action);
Assert.DoesNotContain(expected, playerManager.GetAll());
await Assert.ThrowsAsync<ArgumentNullException>(actionAsync);
Assert.DoesNotContain(expected, await playerManager.GetAll());
}
[Fact]
public void TestAddIfAlreadyExistsThrowsException()
public async Task TestAddIfAlreadyExistsThrowsException()
{
// Arrange
PlayerManager playerManager = new();
// Act
playerManager.Add(new("Kevin"));
void action() => playerManager.Add(new("Kevin"));
await playerManager.Add(new("Kevin"));
async Task actionAsync() => await playerManager.Add(new("Kevin"));
// Assert
Assert.Throws<ArgumentException>(action);
await Assert.ThrowsAsync<ArgumentException>(actionAsync);
}
@ -84,7 +85,7 @@ namespace Tests.Model_UTs.Players
PlayerManager playerManager = new();
// Act
void action() => playerManager.GetOneByID(new("1a276327-75fc-45b9-8854-e7c4101088f8"));
// Assert
@ -95,18 +96,18 @@ namespace Tests.Model_UTs.Players
[InlineData("")]
[InlineData(null)]
[InlineData(" ")]
public void TestGetOneByNameIfInvalidThrowsException(string name)
public async Task TestGetOneByNameIfInvalidThrowsException(string name)
{
// Arrange
PlayerManager playerManager = new();
Player player = new("Bob");
playerManager.Add(player);
await playerManager.Add(player);
// Act
void action() => playerManager.GetOneByName(name);
async Task actionAsync() => await playerManager.GetOneByName(name);
// Assert
Assert.Throws<ArgumentException>(action);
await Assert.ThrowsAsync<ArgumentException>(actionAsync);
}
[Fact]
@ -118,7 +119,7 @@ namespace Tests.Model_UTs.Players
playerManager.Add(player);
// Act
Player result = playerManager.GetOneByName("Clyde");
Player result = playerManager.GetOneByName("Clyde")?.Result;
// Assert
Assert.Null(result);
@ -137,33 +138,33 @@ namespace Tests.Model_UTs.Players
playerManager.Add(expected);
// Act
Player actual = playerManager.GetOneByName(name);
Player actual = playerManager.GetOneByName(name)?.Result;
// Assert
Assert.Equal(expected, actual);
}
[Fact]
public void TestRemoveWorksIfExists()
public async Task TestRemoveWorksIfExists()
{
// Arrange
PlayerManager playerManager = new();
Player p1 = new("Dylan");
playerManager.Add(p1);
await playerManager.Add(p1);
// Act
playerManager.Remove(p1);
// Assert
Assert.DoesNotContain(p1, playerManager.GetAll());
Assert.DoesNotContain(p1, await playerManager.GetAll());
}
[Fact]
public void TestRemoveThrowsExceptionIfGivenNull()
public async Task TestRemoveThrowsExceptionIfGivenNull()
{
// Arrange
PlayerManager playerManager = new();
playerManager.Add(new Player("Dylan"));
await playerManager.Add(new Player("Dylan"));
// Act
void action() => playerManager.Remove(null);
@ -173,37 +174,37 @@ namespace Tests.Model_UTs.Players
}
[Fact]
public void TestRemoveFailsSilentlyIfGivenNonExistent()
public async Task TestRemoveFailsSilentlyIfGivenNonExistent()
{
// Arrange
PlayerManager playerManager = new();
Player player = new("Dylan");
playerManager.Add(player);
await playerManager.Add(player);
Player notPlayer = new("Eric");
// Act
playerManager.Remove(notPlayer);
// Assert
Assert.DoesNotContain(notPlayer, playerManager.GetAll());
Assert.DoesNotContain(notPlayer, await playerManager.GetAll());
}
[Fact]
public void TestUpdateWorksIfValid()
public async Task TestUpdateWorksIfValid()
{
// Arrange
PlayerManager playerManager = new();
Player oldPlayer = new("Dylan");
playerManager.Add(oldPlayer);
await playerManager.Add(oldPlayer);
Player newPlayer = new("Eric");
// Act
playerManager.Update(oldPlayer, newPlayer);
await playerManager.Update(oldPlayer, newPlayer);
// Assert
Assert.DoesNotContain(oldPlayer, playerManager.GetAll());
Assert.Contains(newPlayer, playerManager.GetAll());
Assert.True(playerManager.GetAll().Count() == 1);
Assert.DoesNotContain(oldPlayer, await playerManager.GetAll());
Assert.Contains(newPlayer, await playerManager.GetAll());
Assert.True((await playerManager.GetAll()).Count() == 1);
}
[Theory]
@ -211,20 +212,20 @@ namespace Tests.Model_UTs.Players
[InlineData("Filibert", " fiLibert")]
[InlineData("Filibert", "FIlibert ")]
[InlineData(" Filibert", " filiBErt ")]
public void TestUpdateDiscreetlyUpdatesCaseAndIgnoresExtraSpaceIfOtherwiseSame(string n1, string n2)
public async Task TestUpdateDiscreetlyUpdatesCaseAndIgnoresExtraSpaceIfOtherwiseSame(string n1, string n2)
{
// Arrange
PlayerManager playerManager = new();
Player oldPlayer = new(n1);
playerManager.Add(oldPlayer);
await playerManager.Add(oldPlayer);
Player newPlayer = new(n2);
// Act
playerManager.Update(oldPlayer, newPlayer);
await playerManager.Update(oldPlayer, newPlayer);
// Assert
Assert.Contains(oldPlayer, playerManager.GetAll());
Assert.Contains(newPlayer, playerManager.GetAll());
Assert.Contains(oldPlayer, await playerManager.GetAll());
Assert.Contains(newPlayer, await playerManager.GetAll());
Assert.Equal(oldPlayer, newPlayer);
}
@ -232,62 +233,62 @@ namespace Tests.Model_UTs.Players
[InlineData("")]
[InlineData(" ")]
[InlineData(null)]
public void TestUpdateDoesNotGoWithValidBeforeAndInvalidAfter(string badName)
public async Task TestUpdateDoesNotGoWithValidBeforeAndInvalidAfter(string badName)
{
// Arrange
PlayerManager playerManager = new();
Player oldPlayer = new("Ni!");
playerManager.Add(oldPlayer);
int size1 = playerManager.GetAll().Count();
await playerManager.Add(oldPlayer);
int size1 = (await playerManager.GetAll()).Count();
// Act
Assert.Contains(oldPlayer, playerManager.GetAll());
void action() => playerManager.Update(oldPlayer, new Player(badName));// this is really testing the Player class...
int size2 = playerManager.GetAll().Count();
Assert.Contains(oldPlayer, await playerManager.GetAll());
async Task actionAsync() => await playerManager.Update(oldPlayer, new Player(badName));// this is really testing the Player class...
int size2 = (await playerManager.GetAll()).Count();
// Assert
Assert.Throws<ArgumentException>(action); // thrown by Player constructor
Assert.Contains(oldPlayer, playerManager.GetAll()); // still there
await Assert.ThrowsAsync<ArgumentException>(actionAsync); // thrown by Player constructor
Assert.Contains(oldPlayer, await playerManager.GetAll()); // still there
Assert.True(size1 == size2);
}
[Fact]
public void TestUpdateDoesNotGoWithValidBeforeAndNullAfter()
public async Task TestUpdateDoesNotGoWithValidBeforeAndNullAfter()
{
// Arrange
PlayerManager playerManager = new();
Player oldPlayer = new("Ni!");
playerManager.Add(oldPlayer);
int size1 = playerManager.GetAll().Count();
await playerManager.Add(oldPlayer);
int size1 = (await playerManager.GetAll()).Count();
// Act
Assert.Contains(oldPlayer, playerManager.GetAll());
void action() => playerManager.Update(oldPlayer, null);
int size2 = playerManager.GetAll().Count();
Assert.Contains(oldPlayer, await playerManager.GetAll());
async Task actionAsync() => await playerManager.Update(oldPlayer, null);
int size2 = (await playerManager.GetAll()).Count();
// Assert
Assert.Throws<ArgumentNullException>(action); // thrown by Update()
Assert.Contains(oldPlayer, playerManager.GetAll()); // still there
await Assert.ThrowsAsync<ArgumentNullException>(actionAsync); // thrown by Update()
Assert.Contains(oldPlayer, await playerManager.GetAll()); // still there
Assert.True(size1 == size2);
}
[Fact]
public void TestUpdateDoesNotGoWithValidAfterAndNullBefore()
public async Task TestUpdateDoesNotGoWithValidAfterAndNullBefore()
{
// Arrange
PlayerManager playerManager = new();
Player newPlayer = new("Kevin");
Player oldPlayer = new("Ursula");
playerManager.Add(oldPlayer);
int size1 = playerManager.GetAll().Count();
await playerManager.Add(oldPlayer);
int size1 = (await playerManager.GetAll()).Count();
// Act
void action() => playerManager.Update(null, newPlayer);
int size2 = playerManager.GetAll().Count();
async Task actionAsync() => await playerManager.Update(null, newPlayer);
int size2 = (await playerManager.GetAll()).Count();
// Assert
Assert.Throws<ArgumentNullException>(action); // thrown by Update()
Assert.Contains(oldPlayer, playerManager.GetAll()); // still there
await Assert.ThrowsAsync<ArgumentNullException>(actionAsync); // thrown by Update()
Assert.Contains(oldPlayer, await playerManager.GetAll()); // still there
Assert.True(size1 == size2);
}
@ -295,21 +296,21 @@ namespace Tests.Model_UTs.Players
[InlineData("")]
[InlineData(" ")]
[InlineData(null)]
public void TestUpdateDoesNotGoWithValidAfterAndInvalidBefore(string name)
public async Task TestUpdateDoesNotGoWithValidAfterAndInvalidBefore(string name)
{
// Arrange
PlayerManager playerManager = new();
Player oldPlayer = new("Ursula");
playerManager.Add(oldPlayer);
int size1 = playerManager.GetAll().Count();
await playerManager.Add(oldPlayer);
int size1 = (await playerManager.GetAll()).Count();
// Act
void action() => playerManager.Update(new Player(name), new Player("Vicky"));
int size2 = playerManager.GetAll().Count();
async Task actionAsync() => await playerManager.Update(new Player(name), new Player("Vicky"));
int size2 = (await playerManager.GetAll()).Count();
// Assert
Assert.Throws<ArgumentException>(action); // thrown by Player constructor
Assert.Contains(oldPlayer, playerManager.GetAll()); // still there
await Assert.ThrowsAsync<ArgumentException>(actionAsync); // thrown by Player constructor
Assert.Contains(oldPlayer, await playerManager.GetAll()); // still there
Assert.True(size1 == size2);
}
}

Loading…
Cancel
Save