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

@ -6,7 +6,8 @@ namespace Data.EF
{ {
public class DiceAppDbContext : DbContext, ILoader 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; } public DbSet<PlayerEntity> Players { get; set; }

@ -1,13 +1,15 @@
using Data.EF.Players; using Data.EF.Players;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Model.Games; using Model.Games;
using System.Linq.Expressions;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
namespace Data.EF namespace Data.EF
{ {
public class DiceAppDbContextWithStub : DiceAppDbContext public class DiceAppDbContextWithStub : DiceAppDbContext
{ {
public override MasterOfCeremonies LoadApp() { throw new NotImplementedException(); } // will be async
public override Task<MasterOfCeremonies> LoadApp() { throw new NotImplementedException(); }
public DiceAppDbContextWithStub() { } public DiceAppDbContextWithStub() { }
@ -20,7 +22,7 @@ namespace Data.EF
modelBuilder.Entity<PlayerEntity>().HasData( modelBuilder.Entity<PlayerEntity>().HasData(
new PlayerEntity { ID = Guid.NewGuid(), Name = "Alice" }, // some tests depend on this name 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 = "Clyde" }, // some tests depend on this name
new PlayerEntity { ID = Guid.NewGuid(), Name = "Dahlia" } // 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;
using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.ChangeTracking;
using Model; using Model;
using Model.Players;
using System.Runtime.Intrinsics.Arm;
namespace Data.EF.Players namespace Data.EF.Players
{ {
@ -45,7 +43,7 @@ namespace Data.EF.Players
/// <returns></returns> /// <returns></returns>
/// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception> /// <exception cref="ArgumentException"></exception>
public PlayerEntity Add(PlayerEntity toAdd) public Task<PlayerEntity> Add(PlayerEntity toAdd)
{ {
CleanPlayerEntity(toAdd); CleanPlayerEntity(toAdd);
@ -54,14 +52,21 @@ namespace Data.EF.Players
throw new ArgumentException("this username is already taken", nameof(toAdd)); throw new ArgumentException("this username is already taken", nameof(toAdd));
} }
EntityEntry ee = db.Players.Add(toAdd); return InternalAdd(toAdd);
db.SaveChanges(); }
private async Task<PlayerEntity> InternalAdd(PlayerEntity toAdd)
{
EntityEntry ee = await db.Players.AddAsync(toAdd);
await db.SaveChangesAsync();
return (PlayerEntity)ee.Entity; 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> /// <summary>
@ -72,25 +77,30 @@ namespace Data.EF.Players
/// <exception cref="ArgumentException"></exception> /// <exception cref="ArgumentException"></exception>
/// <exception cref="InvalidOperationException"></exception> /// <exception cref="InvalidOperationException"></exception>
/// <returns></returns> /// <returns></returns>
public PlayerEntity GetOneByName(string name) public Task<PlayerEntity> GetOneByName(string name)
{ {
if (string.IsNullOrWhiteSpace(name)) if (string.IsNullOrWhiteSpace(name))
{ {
throw new ArgumentException("Name property should not be null or whitespace", nameof(name)); throw new ArgumentException("Name property should not be null or whitespace", nameof(name));
} }
name = name.Trim(); 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)) if (string.IsNullOrWhiteSpace(name))
{ {
return false; return false;
} }
name = name.Trim(); 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> /// <summary>
@ -102,8 +112,8 @@ namespace Data.EF.Players
public void Remove(PlayerEntity toRemove) public void Remove(PlayerEntity toRemove)
{ {
CleanPlayerEntity(toRemove); CleanPlayerEntity(toRemove);
bool isPresent = IsPresentByID(toRemove.ID).Result;
if (IsPresentByID(toRemove.ID)) if (isPresent)
{ {
db.Players.Remove(toRemove); db.Players.Remove(toRemove);
db.SaveChanges(); db.SaveChanges();
@ -118,7 +128,7 @@ namespace Data.EF.Players
/// <returns>the updated entity</returns> /// <returns>the updated entity</returns>
/// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception> /// <exception cref="ArgumentException"></exception>
public PlayerEntity Update(PlayerEntity before, PlayerEntity after) public Task<PlayerEntity> Update(PlayerEntity before, PlayerEntity after)
{ {
PlayerEntity[] args = { before, after }; PlayerEntity[] args = { before, after };
@ -132,16 +142,14 @@ namespace Data.EF.Players
throw new ArgumentException("ID cannot be updated", nameof(after)); throw new ArgumentException("ID cannot be updated", nameof(after));
} }
string beforeName = before.Name; return InternalUpdate(before, after);
before.Name = after.Name;
EntityEntry ee = db.Players.Update(before);
db.SaveChanges();
before.Name = beforeName; }
return (PlayerEntity)ee.Entity;
private async Task<PlayerEntity> InternalUpdate(PlayerEntity before, PlayerEntity after)
{
Remove(before);
return await Add(after);
} }
/// <summary> /// <summary>
@ -151,14 +159,14 @@ namespace Data.EF.Players
/// <param name="ID">the ID to look for</param> /// <param name="ID">the ID to look for</param>
/// <returns>PlayerEntity with that ID</returns> /// <returns>PlayerEntity with that ID</returns>
/// <exception cref="InvalidOperationException"></exception> /// <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;
using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.ChangeTracking;
using Model; using Model;
using Model.Players;
using System.Runtime.Intrinsics.Arm;
namespace Data.EF.Players namespace Data.EF.Players
{ {
@ -45,7 +43,7 @@ namespace Data.EF.Players
/// <returns></returns> /// <returns></returns>
/// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception> /// <exception cref="ArgumentException"></exception>
public PlayerEntity Add(PlayerEntity toAdd) public Task<PlayerEntity> Add(PlayerEntity toAdd)
{ {
CleanPlayerEntity(toAdd); CleanPlayerEntity(toAdd);
@ -54,14 +52,21 @@ namespace Data.EF.Players
throw new ArgumentException("this username is already taken", nameof(toAdd)); throw new ArgumentException("this username is already taken", nameof(toAdd));
} }
EntityEntry ee = db.Players.Add(toAdd); return InternalAdd(toAdd);
db.SaveChanges(); }
private async Task<PlayerEntity> InternalAdd(PlayerEntity toAdd)
{
EntityEntry ee = await db.Players.AddAsync(toAdd);
await db.SaveChangesAsync();
return (PlayerEntity)ee.Entity; 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> /// <summary>
@ -72,25 +77,30 @@ namespace Data.EF.Players
/// <exception cref="ArgumentException"></exception> /// <exception cref="ArgumentException"></exception>
/// <exception cref="InvalidOperationException"></exception> /// <exception cref="InvalidOperationException"></exception>
/// <returns></returns> /// <returns></returns>
public PlayerEntity GetOneByName(string name) public Task<PlayerEntity> GetOneByName(string name)
{ {
if (string.IsNullOrWhiteSpace(name)) if (string.IsNullOrWhiteSpace(name))
{ {
throw new ArgumentException("Name property should not be null or whitespace", nameof(name)); throw new ArgumentException("Name property should not be null or whitespace", nameof(name));
} }
name = name.Trim(); 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)) if (string.IsNullOrWhiteSpace(name))
{ {
return false; return false;
} }
name = name.Trim(); 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> /// <summary>
@ -102,8 +112,8 @@ namespace Data.EF.Players
public void Remove(PlayerEntity toRemove) public void Remove(PlayerEntity toRemove)
{ {
CleanPlayerEntity(toRemove); CleanPlayerEntity(toRemove);
bool isPresent = IsPresentByID(toRemove.ID).Result;
if (IsPresentByID(toRemove.ID)) if (isPresent)
{ {
db.Players.Remove(toRemove); db.Players.Remove(toRemove);
db.SaveChanges(); db.SaveChanges();
@ -118,7 +128,7 @@ namespace Data.EF.Players
/// <returns>the updated entity</returns> /// <returns>the updated entity</returns>
/// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception> /// <exception cref="ArgumentException"></exception>
public PlayerEntity Update(PlayerEntity before, PlayerEntity after) public Task<PlayerEntity> Update(PlayerEntity before, PlayerEntity after)
{ {
PlayerEntity[] args = { before, after }; PlayerEntity[] args = { before, after };
@ -132,16 +142,14 @@ namespace Data.EF.Players
throw new ArgumentException("ID cannot be updated", nameof(after)); throw new ArgumentException("ID cannot be updated", nameof(after));
} }
string beforeName = before.Name; return InternalUpdate(before, after);
before.Name = after.Name;
EntityEntry ee = db.Players.Update(before);
db.SaveChanges();
before.Name = beforeName; }
return (PlayerEntity)ee.Entity;
private async Task<PlayerEntity> InternalUpdate(PlayerEntity before, PlayerEntity after)
{
Remove(before);
return await Add(after);
} }
/// <summary> /// <summary>
@ -151,14 +159,14 @@ namespace Data.EF.Players
/// <param name="ID">the ID to look for</param> /// <param name="ID">the ID to look for</param>
/// <returns>PlayerEntity with that ID</returns> /// <returns>PlayerEntity with that ID</returns>
/// <exception cref="InvalidOperationException"></exception> /// <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 interface ILoader
{ {
public MasterOfCeremonies LoadApp(); public Task<MasterOfCeremonies> LoadApp();
} }
} }

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

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

@ -18,11 +18,5 @@
Value = value; Value = value;
StringValue = value.ToString(); 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.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks;
namespace Model.Games namespace Model.Games
{ {
@ -112,13 +113,13 @@ namespace Model.Games
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
/// <exception cref="Exception"></exception> /// <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"); 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> /// <summary>
@ -128,9 +129,9 @@ namespace Model.Games
/// <exception cref="MemberAccessException"></exception> /// <exception cref="MemberAccessException"></exception>
/// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></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()) if (!players.Any())
{ {
throw new MemberAccessException("you are exploring an empty collection\nthis should not have happened"); 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($"Game: {Name}");
sb.Append("\nPlayers:"); sb.Append("\nPlayers:");
foreach (Player player in PlayerManager.GetAll()) foreach (Player player in PlayerManager.GetAll()?.Result)
{ {
sb.Append($" {player.ToString()}"); sb.Append($" {player.ToString()}");
} }

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

@ -1,6 +1,7 @@
using Model.Dice; using Model.Dice;
using Model.Players; using Model.Players;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks;
namespace Model.Games namespace Model.Games
{ {
@ -24,21 +25,21 @@ namespace Model.Games
/// <param name="playerManager"></param> /// <param name="playerManager"></param>
/// <param name="dice"></param> /// <param name="dice"></param>
/// <returns></returns> /// <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); Game game = new(name, playerManager, dice);
return GameManager.Add(game); return await GameManager.Add(game);
} }
/// <summary> /// <summary>
/// plays one turn of the game /// plays one turn of the game
/// </summary> /// </summary>
/// <param name="game">the game from which a turn will be played</param> /// <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.PerformTurn(current);
game.PrepareNextPlayer(current); await game.PrepareNextPlayer(current);
} }
} }

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

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
namespace Model.Players namespace Model.Players
{ {
@ -20,7 +21,7 @@ namespace Model.Players
/// </summary> /// </summary>
/// <param name="toAdd">player to be added</param> /// <param name="toAdd">player to be added</param>
/// <returns>added player</returns> /// <returns>added player</returns>
public Player Add(Player toAdd) public Task<Player> Add(Player toAdd)
{ {
if (toAdd is null) if (toAdd is null)
{ {
@ -31,25 +32,27 @@ namespace Model.Players
throw new ArgumentException("this username is already taken", nameof(toAdd)); throw new ArgumentException("this username is already taken", nameof(toAdd));
} }
players.Add(toAdd); players.Add(toAdd);
return toAdd; return Task.FromResult(toAdd);
} }
/// <summary> /// <summary>
/// finds the player with that name and returns A COPY OF IT /// finds the player with that name and returns it
/// <br/>
/// that copy does not belong to this manager's players, so it should not be modified
/// </summary> /// </summary>
/// <param name="name">a player's unique name</param> /// <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> /// <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); throw new ArgumentException("param should not be null or blank", nameof(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));
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> /// </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 /// so that the only way to modify the collection of players is to use this class's methods
/// </summary> /// </summary>
/// <returns>a readonly enumerable of all this manager's players</returns> /// <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> /// <summary>
/// update a player from <paramref name="before"/> to <paramref name="after"/> /// 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="before">player to be updated</param>
/// <param name="after">player in the state that it needs to be in after the update</param> /// <param name="after">player in the state that it needs to be in after the update</param>
/// <returns>updated player</returns> /// <returns>updated player</returns>
public Player Update(Player before, Player after) public Task<Player> Update(Player before, Player after)
{ {
Player[] args = { before, after }; Player[] args = { before, after };
@ -96,7 +99,7 @@ namespace Model.Players
players.Remove(toRemove); players.Remove(toRemove);
} }
public Player GetOneByID(Guid ID) public Task<Player> GetOneByID(Guid ID)
{ {
throw new NotImplementedException(); 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 Data.EF.Players;
using Microsoft.Data.Sqlite; using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Model.Players;
using System; using System;
using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Xunit; using Xunit;
using Xunit.Sdk;
namespace Tests.Data_UTs.Players namespace Tests.Data_UTs.Players
{ {
@ -33,32 +27,8 @@ namespace Tests.Data_UTs.Players
.Options; .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] [Fact]
public void TestConstructorWhenGivenContextThenConstructs() public async Task TestConstructorWhenGivenContextThenConstructs()
{ {
// Arrange // Arrange
@ -72,7 +42,7 @@ namespace Tests.Data_UTs.Players
// Assert // 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] [Fact]
public void TestAddWhenValidThenValid() public async Task TestAddWhenValidThenValid()
{ {
// Arrange // Arrange
@ -107,8 +77,8 @@ namespace Tests.Data_UTs.Players
{ {
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); mgr = new(db);
mgr.Add(new PlayerEntity() { Name = expectedName }); await mgr.Add(new PlayerEntity() { Name = expectedName });
mgr.Add(new PlayerEntity() { Name = "whatever" }); await mgr.Add(new PlayerEntity() { Name = "whatever" });
// mgr takes care of the SaveChange() calls internally // mgr takes care of the SaveChange() calls internally
// we might use Units of Work later, to optimize our calls to DB // 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(); db.Database.EnsureCreated();
mgr = new(db); mgr = new(db);
Assert.Equal(expectedName, mgr.GetOneByName(expectedName).Name); Assert.Equal(expectedName, (await mgr.GetOneByName(expectedName)).Name);
Assert.Equal(expectedCount, mgr.GetAll().Count()); Assert.Equal(expectedCount, (await mgr.GetAll()).Count());
} }
} }
[Fact] [Fact]
public void TestAddWhenPreExistentThenException() public async Task TestAddWhenPreExistentThenException()
{ {
// Arrange // Arrange
@ -140,12 +110,12 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); mgr = new(db);
mgr.Add(new PlayerEntity() { Name = name }); await mgr.Add(new PlayerEntity() { Name = name });
void action() => mgr.Add(new PlayerEntity() { Name = name }); async Task actionAsync() => await mgr.Add(new PlayerEntity() { Name = name });
// Assert // Assert
Assert.Throws<ArgumentException>(action); await Assert.ThrowsAsync<ArgumentException>(actionAsync);
} }
} }
@ -164,11 +134,11 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); mgr = new(db);
void action() => mgr.Add(null); async Task actionAsync() => await mgr.Add(null);
// Assert // Assert
Assert.Throws<ArgumentNullException>(action); Assert.ThrowsAsync<ArgumentNullException>(actionAsync);
} }
} }
@ -190,11 +160,11 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); mgr = new(db);
void action() => mgr.Add(new PlayerEntity() { Name = name }); async Task actionAsync() => await mgr.Add(new PlayerEntity() { Name = name });
// Assert // Assert
Assert.Throws<ArgumentException>(action); Assert.ThrowsAsync<ArgumentException>(actionAsync);
} }
} }
@ -202,7 +172,7 @@ namespace Tests.Data_UTs.Players
[InlineData(" ")] [InlineData(" ")]
[InlineData(null)] [InlineData(null)]
[InlineData("")] [InlineData("")]
public void TestGetOneByNameWhenInvalidThenException(string name) public async Task TestGetOneByNameWhenInvalidThenException(string name)
{ {
// Arrange // Arrange
@ -215,14 +185,14 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); mgr = new(db);
mgr.Add(new() { Name = "Ernesto" }); await mgr.Add(new() { Name = "Ernesto" });
mgr.Add(new() { Name = "Basil" }); await mgr.Add(new() { Name = "Basil" });
void action() => mgr.GetOneByName(name); async Task actionAsync() => await mgr.GetOneByName(name);
// Assert // 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 ")] [InlineData("Caroline ")]
[InlineData(" Caroline")] [InlineData(" Caroline")]
public void TestGetOneByNameWhenValidAndExistsThenGetsIt(string name) public async Task TestGetOneByNameWhenValidAndExistsThenGetsIt(string name)
{ {
// Arrange // Arrange
@ -246,8 +216,8 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); mgr = new(db);
mgr.Add(expected); await mgr.Add(expected);
mgr.Add(new() { Name = "Philip" }); await mgr.Add(new() { Name = "Philip" });
} }
// Assert // Assert
@ -256,13 +226,13 @@ namespace Tests.Data_UTs.Players
{ {
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); mgr = new(db);
actual = mgr.GetOneByName(name); actual = await mgr.GetOneByName(name);
Assert.Equal(expected, actual); Assert.Equal(expected, actual);
} }
} }
[Fact] [Fact]
public void TestGetOneByNameWhenValidAndNotExistsThenException() public async Task TestGetOneByNameWhenValidAndNotExistsThenException()
{ {
// Arrange // Arrange
@ -276,19 +246,19 @@ namespace Tests.Data_UTs.Players
mgr = new(db); mgr = new(db);
//mgr.Add(expected); //mgr.Add(expected);
mgr.Add(new() { Name = "Brett" }); await mgr.Add(new() { Name = "Brett" });
mgr.Add(new() { Name = "Noah" }); await mgr.Add(new() { Name = "Noah" });
void action() => mgr.GetOneByName("*r^a*éàru é^à"); async Task actionAsync() => await mgr.GetOneByName("*r^a*éàru é^à");
// Assert // Assert
Assert.Throws<InvalidOperationException>(action); await Assert.ThrowsAsync<InvalidOperationException>(actionAsync);
} }
} }
[Fact] [Fact]
public void TestIsPresentByNameWhenValidAndExistsThenTrue() public async Task TestIsPresentByNameWhenValidAndExistsThenTrue()
{ {
// Arrange // Arrange
@ -302,8 +272,8 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); mgr = new(db);
mgr.Add(new() { Name = "Philip" }); await mgr.Add(new() { Name = "Philip" });
mgr.Add(new() { Name = name }); await mgr.Add(new() { Name = name });
} }
// Assert // Assert
@ -313,7 +283,7 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); 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(" ")] [InlineData(" ")]
[InlineData(null)] [InlineData(null)]
[InlineData("Barbara")] [InlineData("nowaythatthisnameisalreadyinourdatabase")]
public void TestIsPresentByNameWhenInvalidOrNonExistentThenFalse(string name) public async Task TestIsPresentByNameWhenInvalidOrNonExistentThenFalse(string name)
{ {
// Arrange // Arrange
@ -335,8 +305,8 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); mgr = new(db);
mgr.Add(new() { Name = "Herman" }); await mgr.Add(new() { Name = "Herman" });
mgr.Add(new() { Name = "Paulo" }); await mgr.Add(new() { Name = "Paulo" });
} }
// Assert // Assert
@ -346,7 +316,7 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); 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; PlayerDbManager mgr;
PlayerEntity toRemove = new() { Name = "Filibert" }; PlayerEntity toRemove = new() { ID = Guid.NewGuid(), Name = "Please!" };
using (DiceAppDbContext db = new(options))
{
db.Database.EnsureCreated();
mgr = new(db);
mgr.Add(new() { Name = "Xavier" });
mgr.Add(toRemove);
}
// Act // Act
using (DiceAppDbContext db = new(options)) using (DiceAppDbContextWithStub db = new(options))
{ {
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); mgr = new(db);
mgr.Add(toRemove); // calls SaveChangesAsync()
mgr.Remove(toRemove); mgr.Remove(toRemove);
} }
// Assert // Assert
using (DiceAppDbContext db = new(options)) using (DiceAppDbContextWithStub db = new(options))
{ {
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); mgr = new(db);
Assert.DoesNotContain(toRemove, mgr.GetAll()); Assert.DoesNotContain(toRemove, db.Players);
} }
} }
[Fact] [Fact]
public void TestRemoveWhenNonExistentThenStillNonExistent() public async Task TestRemoveWhenNonExistentThenStillNonExistent()
{ {
// Arrange // Arrange
PlayerDbManager mgr; PlayerDbManager mgr;
PlayerEntity toRemove = new() { Name = "Filibert" }; PlayerEntity toRemove = new() { ID = Guid.NewGuid(), Name = "Filibert" };
// Act // Act
@ -427,7 +389,7 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); mgr = new(db);
mgr.Add(new() { Name = "Bert" }); await mgr.Add(new() { ID = Guid.NewGuid(), Name = "Bert" });
mgr.Remove(toRemove); mgr.Remove(toRemove);
} }
@ -438,14 +400,14 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); mgr = new(db);
Assert.DoesNotContain(toRemove, mgr.GetAll()); Assert.DoesNotContain(toRemove, await mgr.GetAll());
} }
} }
[Theory] [Theory]
[InlineData("filiBert")] [InlineData("filiBert")]
[InlineData("Bertrand")] [InlineData("Bertrand")]
public void TestUpdateWhenValidThenUpdates(string name) public async Task TestUpdateWhenValidThenUpdates(string name)
{ {
// Arrange // Arrange
@ -462,8 +424,8 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); mgr = new(db);
mgr.Add(before); await mgr.Add(before);
mgr.Update(before, after); await mgr.Update(before, after);
} }
// Assert // Assert
@ -473,8 +435,8 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); mgr = new(db);
Assert.DoesNotContain(before, mgr.GetAll()); Assert.DoesNotContain(before, await mgr.GetAll());
Assert.Contains(after, mgr.GetAll()); Assert.Contains(after, await mgr.GetAll());
} }
} }
@ -482,7 +444,7 @@ namespace Tests.Data_UTs.Players
[InlineData("Valerie")] [InlineData("Valerie")]
[InlineData("Valerie ")] [InlineData("Valerie ")]
[InlineData(" Valerie")] [InlineData(" Valerie")]
public void TestUpdateWhenSameThenKeepsAndWorks(string name) public async Task TestUpdateWhenSameThenKeepsAndWorks(string name)
{ {
// Arrange // Arrange
@ -500,8 +462,8 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); mgr = new(db);
mgr.Add(before); await mgr.Add(before);
mgr.Update(before, after); await mgr.Update(before, after);
} }
// Assert // Assert
@ -511,14 +473,14 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); mgr = new(db);
Assert.Contains(before, mgr.GetAll()); Assert.Contains(before, await mgr.GetAll());
Assert.Contains(after, mgr.GetAll()); Assert.Contains(after, await mgr.GetAll());
} }
} }
[Fact] [Fact]
public void TestUpdateWhenNewIDThenException() public async Task TestUpdateWhenNewIDThenException()
{ {
// Arrange // Arrange
@ -534,12 +496,12 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); mgr = new(db);
mgr.Add(before); await mgr.Add(before);
void action() => mgr.Update(before, after); async Task actionAsync() => await mgr.Update(before, after);
// Assert // Assert
Assert.Throws<ArgumentException>(action); await Assert.ThrowsAsync<ArgumentException>(actionAsync);
} }
} }
@ -547,7 +509,7 @@ namespace Tests.Data_UTs.Players
[InlineData("")] [InlineData("")]
[InlineData(" ")] [InlineData(" ")]
[InlineData(null)] [InlineData(null)]
public void TestUpdateWhenInvalidThenException(string name) public async Task TestUpdateWhenInvalidThenException(string name)
{ {
// Arrange // Arrange
@ -564,17 +526,17 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); mgr = new(db);
mgr.Add(before); await mgr.Add(before);
void action() => mgr.Update(before, after); async Task actionAsync() => await mgr.Update(before, after);
// Assert // Assert
Assert.Throws<ArgumentException>(action); await Assert.ThrowsAsync<ArgumentException>(actionAsync);
} }
} }
[Fact] [Fact]
public void TestUpdateWhenNullThenException() public async Task TestUpdateWhenNullThenException()
{ {
// Arrange // Arrange
@ -589,17 +551,17 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); mgr = new(db);
mgr.Add(before); await mgr.Add(before);
void action() => mgr.Update(before, null); async Task actionAsync() => await mgr.Update(before, null);
// Assert // Assert
Assert.Throws<ArgumentNullException>(action); await Assert.ThrowsAsync<ArgumentNullException>(actionAsync);
} }
} }
[Fact] [Fact]
public void TestGetOneByIDWhenExistsThenGetsIt() public async Task TestGetOneByIDWhenExistsThenGetsIt()
{ {
// Arrange // Arrange
@ -616,7 +578,7 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); mgr = new(db);
mgr.Add(expected); await mgr.Add(expected);
} }
// Assert // Assert
@ -625,13 +587,13 @@ namespace Tests.Data_UTs.Players
{ {
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); mgr = new(db);
actual = mgr.GetOneByID(id); actual = await mgr.GetOneByID(id);
Assert.Equal(expected, actual); Assert.Equal(expected, actual);
} }
} }
[Fact] [Fact]
public void TestGetOneByIDWhenNotExistsThenException() public async Task TestGetOneByIDWhenNotExistsThenExceptionAsync()
{ {
// Arrange // Arrange
@ -649,18 +611,18 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); mgr = new(db);
mgr.Add(expected); await mgr.Add(expected);
void action() => mgr.GetOneByID(otherId); async Task actionAsync() => await mgr.GetOneByID(otherId);
// Assert // Assert
Assert.Throws<InvalidOperationException>(action); await Assert.ThrowsAsync<InvalidOperationException>(actionAsync);
} }
} }
[Fact] [Fact]
public void TestIsPresentbyIdWhenExistsThenTrue() public async Task TestIsPresentbyIdWhenExistsThenTrue()
{ {
// Arrange // Arrange
@ -674,7 +636,7 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); mgr = new(db);
mgr.Add(new() { ID = id, Name = "Bobby" }); await mgr.Add(new() { ID = id, Name = "Bobby" });
} }
// Assert // Assert
@ -684,12 +646,12 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); mgr = new(db);
Assert.True(mgr.IsPresentByID(id)); Assert.True(await mgr.IsPresentByID(id));
} }
} }
[Fact] [Fact]
public void TestIsPresentbyIdWhenExistsThenFalse() public async Task TestIsPresentbyIdWhenNotExistsThenFalse()
{ {
// Arrange // Arrange
@ -698,6 +660,9 @@ namespace Tests.Data_UTs.Players
Guid otherId = Guid.NewGuid(); Guid otherId = Guid.NewGuid();
PlayerEntity presentEntity;
PlayerEntity absentEntity;
// Act // Act
using (DiceAppDbContext db = new(options)) using (DiceAppDbContext db = new(options))
@ -705,7 +670,10 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); 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 // Assert
@ -715,7 +683,7 @@ namespace Tests.Data_UTs.Players
db.Database.EnsureCreated(); db.Database.EnsureCreated();
mgr = new(db); 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.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Tests.Data_UTs.Games;
using Xunit; using Xunit;
namespace Tests.Model_UTs.Games namespace Tests.Model_UTs.Games
{ {
public class GameManagerTest public class GameManagerTest
{ {
private readonly MasterOfCeremonies stubGameRunner = new Stub().LoadApp(); private readonly MasterOfCeremonies stubGameRunner = new Stub().LoadApp()?.Result;
[Fact] [Fact]
public void TestConstructorReturnsEmptyEnumerable() public async Task TestConstructorReturnsEmptyEnumerableAsync()
{ {
// Arrange // Arrange
GameManager gm = new(); GameManager gm = new();
IEnumerable<Game> expected; IEnumerable<Game> expected;
IEnumerable<Game> actual; IEnumerable<Game> actual;
// Act // Act
expected = new Collection<Game>(); expected = new Collection<Game>();
actual = gm.GetAll(); actual = await gm.GetAll();
// Assert // Assert
Assert.Equal(expected, actual); Assert.Equal(expected, actual);
} }
[Fact] [Fact]
public void TestAddWhenGamesThenDoAddAndReturnGames() public async Task TestAddWhenGamesThenDoAddAndReturnGamesAsync()
{ {
// Arrange // Arrange
GameManager gm = new(); GameManager gm = new();
Game game1 = stubGameRunner.GameManager.GetAll().First(); Game game1 = (await stubGameRunner.GameManager.GetAll()).First();
Game game2 = stubGameRunner.GameManager.GetAll().Last(); Game game2 = (await stubGameRunner.GameManager.GetAll()).Last();
// Act // Act
IEnumerable<Game> expected = new List<Game>() { game1, game2 }.AsEnumerable(); IEnumerable<Game> expected = new List<Game>() { game1, game2 }.AsEnumerable();
IEnumerable<Game> actual = new List<Game>() IEnumerable<Game> actual = new List<Game>()
{ {
gm.Add(game1), await gm.Add(game1),
gm.Add(game2) await gm.Add(game2)
}; };
// Assert // Assert
@ -54,17 +55,17 @@ namespace Tests.Model_UTs.Games
} }
[Fact] [Fact]
public void TestAddWhenNullThenThrowsException() public async Task TestAddWhenNullThenThrowsException()
{ {
// Arrange // Arrange
GameManager gm = new(); GameManager gm = new();
// Act // 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
Assert.Throws<ArgumentNullException>(action); await Assert.ThrowsAsync<ArgumentNullException>(actionAsync);
Assert.DoesNotContain(null, stubGameRunner.GameManager.GetAll()); Assert.DoesNotContain(null, await stubGameRunner.GameManager.GetAll());
} }
[Fact] [Fact]
@ -85,40 +86,40 @@ namespace Tests.Model_UTs.Games
[InlineData("")] [InlineData("")]
[InlineData(null)] [InlineData(null)]
[InlineData(" ")] [InlineData(" ")]
public void TestGetOneByNameWhenInvalidThenThrowsException(string name) public async Task TestGetOneByNameWhenInvalidThenThrowsExceptionAsync(string name)
{ {
// Arrange // Arrange
GameManager gm = new(); GameManager gm = new();
// Act // Act
void action() => gm.GetOneByName(name); async Task actionAsync() => await gm.GetOneByName(name);
// Assert // Assert
Assert.Throws<ArgumentException>(action); await Assert.ThrowsAsync<ArgumentException>(actionAsync);
} }
[Fact] [Fact]
public void TestGetOneByNameWhenValidButNotExistThenReturnNull() public async Task TestGetOneByNameWhenValidButNotExistThenReturnNullAsync()
{ {
// Arrange // Arrange
GameManager gm = new(); GameManager gm = new();
// Act // Act
Game result = gm.GetOneByName("thereisbasicallynowaythatthisgamenamealreadyexists"); Game result = await gm.GetOneByName("thereisbasicallynowaythatthisgamenamealreadyexists");
// Assert // Assert
Assert.Null(result); Assert.Null(result);
} }
[Fact] [Fact]
public void TestGetOneByNameWhenValidThenReturnGame() public async Task TestGetOneByNameWhenValidThenReturnGameAsync()
{ {
// Arrange // Arrange
GameManager gm = new(); GameManager gm = new();
Game game = stubGameRunner.GameManager.GetAll().First(); Game game = (await stubGameRunner.GameManager.GetAll()).First();
// Act // Act
Game actual = gm.Add(game); Game actual = await gm.Add(game);
Game expected = game; Game expected = game;
// Assert // Assert
@ -126,19 +127,19 @@ namespace Tests.Model_UTs.Games
} }
[Fact] [Fact]
public void TestWhenRemoveExistsThenSucceeds() public async Task TestWhenRemoveExistsThenSucceeds()
{ {
// Arrange // Arrange
GameManager gm = new(); GameManager gm = new();
Game game = new("blargh", new PlayerManager(), stubGameRunner.GameManager.GetAll().First().Dice); Game game = new("blargh", new PlayerManager(), (await stubGameRunner.GameManager.GetAll()).First().Dice);
gm.Add(game); await gm.Add(game);
// Act // Act
gm.Remove(game); gm.Remove(game);
// Assert // Assert
Assert.DoesNotContain(game, gm.GetAll()); Assert.DoesNotContain(game, await gm.GetAll());
} }
[Fact] [Fact]
@ -155,46 +156,46 @@ namespace Tests.Model_UTs.Games
} }
[Fact] [Fact]
public void TestRemoveWhenGivenNonExistentThenFailsSilently() public async Task TestRemoveWhenGivenNonExistentThenFailsSilentlyAsync()
{ {
// Arrange // Arrange
IManager<Game> gm = stubGameRunner.GameManager; IManager<Game> gm = stubGameRunner.GameManager;
Game notGame = new("blargh", new PlayerManager(), stubGameRunner.GameManager.GetAll().First().Dice); Game notGame = new("blargh", new PlayerManager(), (await stubGameRunner.GameManager.GetAll()).First().Dice);
IEnumerable<Game> expected = stubGameRunner.GameManager.GetAll(); IEnumerable<Game> expected = await stubGameRunner.GameManager.GetAll();
// Act // Act
gm.Remove(notGame); gm.Remove(notGame);
IEnumerable<Game> actual = gm.GetAll(); IEnumerable<Game> actual = await gm.GetAll();
// Assert // Assert
Assert.Equal(actual, expected); Assert.Equal(actual, expected);
} }
[Fact] [Fact]
public void TestUpdateWhenValidThenSucceeds() public async Task TestUpdateWhenValidThenSucceeds()
{ {
// Arrange // Arrange
GameManager gm = new(); GameManager gm = new();
string oldName = "blargh"; string oldName = "blargh";
string newName = "blargh2.0"; string newName = "blargh2.0";
Game game = new(oldName, new PlayerManager(), stubGameRunner.GameManager.GetAll().First().Dice); Game game = new(oldName, new PlayerManager(), (await stubGameRunner.GameManager.GetAll()).First().Dice);
game.PlayerManager.Add(new("Alice")); await game.PlayerManager.Add(new("Alice"));
gm.Add(game); await gm.Add(game);
Game oldGame = gm.GetAll().First(); Game oldGame = (await gm.GetAll()).First();
Game newGame = new(newName, oldGame.PlayerManager, oldGame.Dice); Game newGame = new(newName, oldGame.PlayerManager, oldGame.Dice);
// Act // Act
int expectedSize = gm.GetAll().Count(); int expectedSize = (await gm.GetAll()).Count();
gm.Update(oldGame, newGame); await gm.Update(oldGame, newGame);
int actualSize = gm.GetAll().Count(); int actualSize = (await gm.GetAll()).Count();
// Assert // Assert
Assert.NotEqual(oldName, newName); Assert.NotEqual(oldName, newName);
Assert.DoesNotContain(oldGame, gm.GetAll()); Assert.DoesNotContain(oldGame, await gm.GetAll());
Assert.Contains(newGame, gm.GetAll()); Assert.Contains(newGame, await gm.GetAll());
Assert.Equal(expectedSize, actualSize); Assert.Equal(expectedSize, actualSize);
} }
@ -202,57 +203,57 @@ namespace Tests.Model_UTs.Games
[InlineData("")] [InlineData("")]
[InlineData(" ")] [InlineData(" ")]
[InlineData(null)] [InlineData(null)]
public void TestUpdateWhenValidBeforeAndInvalidAfterThenDoesNotGo(string badName) public async Task TestUpdateWhenValidBeforeAndInvalidAfterThenDoesNotGoAsync(string badName)
{ {
// Arrange // Arrange
IManager<Game> gm = stubGameRunner.GameManager; IManager<Game> gm = stubGameRunner.GameManager;
int expectedSize = gm.GetAll().Count(); int expectedSize = (await gm.GetAll()).Count();
Game oldGame = gm.GetAll().First(); Game oldGame = (await gm.GetAll()).First();
// Act // Act
void action() => gm.Update(oldGame, new(badName, oldGame.PlayerManager, oldGame.Dice)); void action() => gm.Update(oldGame, new(badName, oldGame.PlayerManager, oldGame.Dice));
int actualSize = gm.GetAll().Count(); int actualSize = (await gm.GetAll()).Count();
// Assert // Assert
Assert.Throws<ArgumentException>(action); // thrown by constructor 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); Assert.Equal(expectedSize, actualSize);
} }
[Fact] [Fact]
public void TestUpdateWhenValidBeforeAndNullAfterThenDoesNotGo() public async Task TestUpdateWhenValidBeforeAndNullAfterThenDoesNotGoAsync()
{ {
// Arrange // Arrange
IManager<Game> gm = stubGameRunner.GameManager; IManager<Game> gm = stubGameRunner.GameManager;
int expectedSize = gm.GetAll().Count(); int expectedSize = (await gm.GetAll()).Count();
Game oldGame = gm.GetAll().First(); Game oldGame = (await gm.GetAll()).First();
// Act // Act
void action() => gm.Update(oldGame, null); async Task actionAsync() => await gm.Update(oldGame, null);
int actualSize = gm.GetAll().Count(); int actualSize = (await gm.GetAll()).Count();
// Assert // Assert
Assert.Throws<ArgumentNullException>(action); // thrown by constructor await Assert.ThrowsAsync<ArgumentNullException>(actionAsync); // thrown by constructor
Assert.Contains(oldGame, gm.GetAll()); // still there Assert.Contains(oldGame, await gm.GetAll()); // still there
Assert.True(expectedSize == actualSize); Assert.True(expectedSize == actualSize);
} }
[Fact] [Fact]
public void TestUpdateDoesNotGoWithValidAfterAndNullBefore() public async Task TestUpdateDoesNotGoWithValidAfterAndNullBefore()
{ {
// Arrange // Arrange
IManager<Game> gm = stubGameRunner.GameManager; IManager<Game> gm = stubGameRunner.GameManager;
int expectedSize = gm.GetAll().Count(); int expectedSize = (await gm.GetAll()).Count();
Game oldGame = gm.GetAll().First(); Game oldGame = (await gm.GetAll()).First();
// Act // Act
void action() => gm.Update(null, new("newgamename", oldGame.PlayerManager, oldGame.Dice)); async Task actionAsync() => await gm.Update(null, new("newgamename", oldGame.PlayerManager, oldGame.Dice));
int actualSize = gm.GetAll().Count(); int actualSize = (await gm.GetAll()).Count();
// Assert // Assert
Assert.Throws<ArgumentNullException>(action); // thrown by constructor await Assert.ThrowsAsync<ArgumentNullException>(actionAsync); // thrown by constructor
Assert.Contains(oldGame, gm.GetAll()); // still there Assert.Contains(oldGame, await gm.GetAll()); // still there
Assert.True(expectedSize == actualSize); Assert.True(expectedSize == actualSize);
} }
@ -260,20 +261,20 @@ namespace Tests.Model_UTs.Games
[InlineData("")] [InlineData("")]
[InlineData(" ")] [InlineData(" ")]
[InlineData(null)] [InlineData(null)]
public void TestUpdateWhenInvalidBeforeAndValidAfterThenDoesNotGo(string badName) public async Task TestUpdateWhenInvalidBeforeAndValidAfterThenDoesNotGoAsync(string badName)
{ {
// Arrange // Arrange
IManager<Game> gm = stubGameRunner.GameManager; IManager<Game> gm = stubGameRunner.GameManager;
int expectedSize = gm.GetAll().Count(); int expectedSize = (await gm.GetAll()).Count();
Game oldGame = gm.GetAll().First(); Game oldGame = (await gm.GetAll()).First();
// Act // Act
void action() => gm.Update(new(badName, oldGame.PlayerManager, oldGame.Dice), new("valid", oldGame.PlayerManager, oldGame.Dice)); 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
Assert.Throws<ArgumentException>(action); // thrown by constructor 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); Assert.True(expectedSize == actualSize);
} }

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

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

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

Loading…
Cancel
Save